Я изучаю замену некоторого кода на код кодом python и используя pypy в качестве интерпретатора. В коде много операций с списком/словарем. Поэтому, чтобы получить смутное представление о производительности pypy vs C, я пишу алгоритмы сортировки. Чтобы проверить все мои функции чтения, я написал сортировку пузырьков, как в python, так и в C++. CPython, конечно, сосет 6.468s, pypy пришел в 0.366s и C++ в 0.229s. Затем я вспомнил, что забыл -O3 на C++-коде, и время перешло к 0.042s. Для 32768 набора данных C++ с -O3 всего 2,588 с, а pypy - 19,65 с. Есть ли что-нибудь, что я могу сделать, чтобы ускорить мой код на Python (кроме того, конечно, используя лучший алгоритм сортировки) или как я использую pypy (какой-то флаг или что-то еще)?Оптимизация Pypy (python)
Python код (модуль read_nums опускает, так как это время тривиально: 0.036s на 32768 наборе данных):
import read_nums
import sys
nums = read_nums.read_nums(sys.argv[1])
done = False
while not done:
done = True
for i in range(len(nums)-1):
if nums[i] > nums[i+1]:
nums[i], nums[i+1] = nums[i+1], nums[i]
done = False
$ time pypy-c2.0 bubble_sort.py test_32768_1.nums
real 0m20.199s
user 0m20.189s
sys 0m0.009s
C код (функция read_nums снова опускает, так как занимает мало времени: 0.017s):
#include <iostream>
#include "read_nums.h"
int main(int argc, char** argv)
{
std::vector<int> nums;
int count, i, tmp;
bool done;
if(argc < 2)
{
std::cout << "Usage: " << argv[0] << " filename" << std::endl;
return 1;
}
count = read_nums(argv[1], nums);
done = false;
while(!done)
{
done = true;
for(i=0; i<count-1; ++i)
{
if(nums[i] > nums[i+1])
{
tmp = nums[i];
nums[i] = nums[i+1];
nums[i+1] = tmp;
done = false;
}
}
}
for(i=0; i<count; ++i)
{
std::cout << nums[i] << ", ";
}
return 0;
}
$ time ./bubble_sort test_32768_1.nums > /dev/null
real 0m2.587s
user 0m2.586s
sys 0m0.001s
PS Некоторые цифры, приведенные в первом абзаце, немного отличаются от цифр, потому что это числа, которые я получил в первый раз.
Дальнейшие усовершенствования:
- Только что попробовал xrange вместо диапазона и время работы пошел 16.370s.
- Переведено с кода с
done = False
до последнегоdone = False
в функции, теперь скорость 8.771-8.834s.
Что произойдет, если вы используете переменную tmp, как в коде c? – Claudiu
W/xrange требуется 19.431s, w/xrange и tmp требуется 19.760s. Не знаю, почему мой xrange просто так сильно регрессировал. – CrazyCasta
Хорошо, xrange no tmp был, по-видимому, выбросом, я запускал его еще 5 раз и менял 16.385s-17.158s. С переменной tmp 5 раз она колебалась от 18.923s-19.444s. – CrazyCasta