我正在考虑用python代码替换一些C代码并使用pypy作为解释器。代码做了很多列表/字典操作。因此,为了弄清楚pypy vs C的性能,我正在编写排序算法。为了测试我所有的读取函数,我使用python和C++编写了一个冒泡排序。 CPython当然是6.468s,pypy是0.366s,C++是0.229s。然后我想起我已经忘记了-O3的C++代码,时间到了0.042s。对于32768数据集,-O3的C++只有2.588s,pypy是19.65s。有什么我可以做,以加快我的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。
如果使用像c代码中那样的tmp变量会发生什么? – Claudiu 2013-03-27 17:59:36
W/xrange需要19.431s,w/xrange和tmp需要19.760s。不知道为什么我的xrange刚刚退步。 – CrazyCasta 2013-03-27 18:23:10
好吧,xrange no tmp显然是一个异常值,我跑了5次,它的范围是16.385s-17.158s。 tmp变量为5次,范围从18.923s-19.444s。 – CrazyCasta 2013-03-27 18:29:43