我正在考虑用 python 代码替换一些 C 代码并使用 pypy 作为解释器。该代码执行大量列表/字典操作。因此,为了对 pypy 与 C 的性能有一个模糊的了解,我正在编写排序算法。为了测试我所有的读取函数,我用 python 和 C++ 编写了一个冒泡排序。当然,CPython 的成绩很差,为 6.468 秒,pypy 为 0.366 秒,C++ 为 0.229 秒。然后我想起我在C++代码中忘记了-O3,时间变成了0.042秒。对于 32768 数据集,带有 -O3 的 C++ 仅需要 2.588 秒,而 pypy 则需要 19.65 秒。我可以做些什么来加速我的 python 代码(当然除了使用更好的排序算法)或者如何使用 pypy (一些标志或其他东西)?
Python 代码(省略了 read_nums 模块,因为它的时间很简单:32768 数据集上的时间为 0.036 秒):
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
P.S.第一段中给出的一些数字与之前的数字略有不同,因为它们是我第一次得到的数字。
进一步改进:
- 刚刚尝试使用 xrange 而不是 range,运行时间达到了 16.370 秒。
- 将函数中从第一个
done = False
开始的代码移至最后一个done = False
,速度现在为 8.771-8.834 秒。
最佳答案
回答这个问题最相关的方法是注意 C、CPython 和 PyPy 的速度并没有恒定的差异:它最重要地取决于所做的事情和编写的方式。例如,如果您的 C 代码执行诸如遍历数组之类的幼稚操作,而“等效”Python 代码自然会使用字典,则只要数组足够长,任何 Python 实现都比 C 更快。当然,大多数现实生活中的例子并非如此,但同样的论点在较小程度上仍然适用。没有一种万能的方法可以预测用 C 编写的程序或用 Python 重写并在 CPython 或 PyPy 上运行的程序的相对速度。
显然,有关于这些相对速度的指导原则:在小型算法示例中,您可以预期 PyPy 的速度接近“gcc -O0”的速度。在您的示例中,它“仅”慢了 1.6 倍。我们可能会帮助您优化它,甚至找到 PyPy 中缺少的优化,以获得 10% 或 30% 的速度提升。但这只是一个小例子,与您的实际程序无关。由于上述原因,我们在这里获得的速度仅与您最终获得的速度存在模糊关系。
我只能说,为了清晰起见,将代码从 C 重写为 Python,特别是当 C 变得过于困惑而无法进一步开发时,从长远来看显然是一个胜利 --- 即使在最后你需要用C再次重写它的一些部分。 PyPy 的目标是减少这种需求。虽然很高兴说没有人再需要 C,但事实并非如此 :-)
关于python - Pypy(Python)优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15665429/