阅读pypy官网的介绍,有一些优化tips记录如下。
首先pypy会在执行循环时,跟踪循环执行,将循环体编译成机器码,并优化,观察是否速度有改善,所以pypy对循环体效果特别明显,循环执行得次数越多,编译和warm up的耗时占比就越小,优势就体现出来,否则它反而更慢。
s = '1'
count = 0
for i in xrange(1, 1000000):
count += int(s*3)
count += int(s*2)
print(count)
速度比较:
#python
real 0m0.751s
user 0m0.740s
sys 0m0.004s
#pypy
real 0m0.038s
user 0m0.026s
sys 0m0.012s
pypy会改善索引全局变量的速度,上面的代码加上一句近似冗余的代码,对于python就会更快,但是对于pypy则没有区别,因为python里,局部索引比全局更快:
s = '1'
count = 0
int = int
for i in xrange(1, 1000000):
count += int(s*3)
count += int(s*2)
print(count)
耗时为:
real 0m0.728s
user 0m0.723s
sys 0m0.000s
所以在python里,尽量少引用不必要的外面包是有好处的,但是对于pypy则没有区别。
pypy会将函数调用内联,也就是c++里的inline,所以在递归调用频繁的情况下,pypy的优化也会效果明显。
在字符串拼接时,pypy会提前预测好最终的字符串长度,从而一次性分配足够的内存,所以''.join(str_list)和str1 + str2 + str3,这类字符串拼接操作,pypy也会快得多。
特别注意:
1. locals(), globals(), sys._getframe(), sys.exc_info(), and sys.settrace这些函数的使用,会让pypy关闭实时编译优化,反而会有更多耗时。
2. csv和cPickle等库在CPython里是使用c语言实现的,在pypy里使用反而会更慢(不包含json库)。
3. 有C语言扩展的模块,很多需要重新编译或者使用纯python改写,如果是通过命令安装,也不能直接使用pip安装,需要使用pypy,如:pypy -m pip install Pillow==3.0.0
其实:Pyston项目作为pypy的竞品,也在如火如荼的发展中。