利用pypy性能加速与python的规则



我已经编写了一个python程序,并使用pypy和python运行它我插入了一些计时打印来测量性能差异。在某些情况下,加速是10倍,在其他情况下没有变化。有人能解释一下在编写程序时是否有规则可循吗为了利用pypy提供的潜在加速?例如,避免某些语法,更喜欢某些数据结构而不是其他。。。。

我发现的速度在12倍到1.5倍之间

PyPy在纯数字密集型代码中往往很快热循环处理(小(整数/浮点数,因为它可以直接使用本机类型而不是可变大小的动态整数/浮点对象。它仍然比本机编译的C/C++代码慢,因为它需要在运行时检查类型并在运行时编译代码。

PyPy不喜欢(大型(动态代码。它使用了一个跟踪实时编译器,可以跟踪代码的哪一部分更有可能被执行,并在运行时动态编译该路径(如果经常执行的话(。当有许多执行的路径动态更改时,JIT的开销可能很大,在最坏的情况下,PyPy可以选择不编译任何路径。问题是PyPy回退解释器比CPython的慢(因为它能够在运行时跟踪和编译代码(。支持一些动态特性,如框架内省,但速度较慢(因为代码预计不会大量使用它(。

PyPy对于短运行脚本来说并不快,因为JIT必须在运行时编译代码,并且JIT或使用回退解释器(比CPython慢(的开销可能高于仅使用CPython为此类脚本解释代码。

PyPy使用垃圾回收器(GC(,而CPython使用自动引用计数(ARC(。GC可以更快地分配/释放许多对象(尤其是小的临时对象(,但它们需要跟踪活动对象,以知道哪些对象已死亡,然后释放它们。这意味着处理大量引用和常规对象分配的代码实际上可能会更慢。例如,这包括基于图的动态数据结构

C绑定API(C扩展和C类型,但不是CFFI(往往比CPython慢(主要是因为它最初是为CPython设计的(。这意味着使用PyPy,调用大量封装的C函数的粘合代码实际上会慢一些。在这种情况下,最近已经做了很多工作来显著提高PyPy的性能,但AFAIK-PyPy仍然较慢。用例的一个例子是对大型Numpy数组的操作(对于小型数组,像Numba这样的嵌入式JIT当然更好(,以及CSV和pickle包。

字符串操作往往较慢,尤其是字符串串联。一个原因是CPython使用高效的算法进行字符串操作,这些算法经过了很好的优化并用C编写,而牺牲了庞大而复杂的代码库。对于小型PyPy团队来说,这是一项重要的工作,他们需要重新实现这一点,并通过JIT和GC的额外复杂性来维护它。因此,操作可能无法很好地优化。关于级联,效率低下的原因是JIT无法优化中间副本。话虽如此,请注意,无论如何都应该避免字符串附加循环。

生成器往往比简单的基本循环慢越简单越好。人们不应该期望JIT在运行时执行复杂而昂贵的优化,因为与代码的其余部分相比,JIT的开销不应该太大(PyPy不知道代码提前花费的时间(。

全局变量在CPython中速度较慢,但在PyPy中则不然。话虽如此,它们无论如何都不应该被用于软件工程的原因。

这是一个非常广泛的主题。在评估给定Python代码的性能时,还有许多其他有趣的地方需要考虑。有关更多信息,请阅读:

  • https://www.pypy.org/performance.html(性能提示(
  • https://speed.pypy.org(基准(
  • https://www.pypy.org/blog(关于PyPy发展的文章(

没有硬性规定。PyPy常见问题解答中有一些提示https://doc.pypy.org/en/latest/faq.html#how-法斯特是个变态。PyPy可以JIT热python代码,并且可以使存储一种类型的对象(int、float、string(的列表、字典和元组更加高效。

最新更新