python性能优化
python为什么性能差:
从上图可以看出,不同的case,python比C++慢了几倍到几十倍。
Be pythonic
- 使用迭代器iterator,for example:
- 判断是否是同一个对象使用 is 而不是 ==
- 判断一个对象是否在一个集合中,使用set而不是list
- 利用短路求值特性,把“短路”概率过的逻辑表达式写在前面。其他的lazy ideas也是可以的
- 对于大量字符串的累加,使用join操作
- 使用for else(while else)语法
- 交换两个变量的值使用: a, b = b, a
基于profile的优化
python profilers
# -*- coding: UTF-8 -*- from cProfile import Profile
import math
def foo():
return foo1() def foo1():
return foo2() def foo2():
return foo3() def foo3():
return foo4() def foo4():
return "this call tree seems ugly, but it always happen" def bar():
ret = 0
for i in xrange(10000):
ret += i * i + math.sqrt(i)
return ret def main():
for i in range(100000):
if i % 10000 == 0:
bar()
else:
foo() if __name__ == '__main__':
prof = Profile()
prof.runcall(main)
prof.print_stats()
#prof.dump_stats('test.prof') # dump profile result to test.prof
code for profile
运行结果如下:

对于上面的的输出,每一个字段意义如下:
profile GUI tools

qcachegrind确实要比visualpytune强大。从上图可以看到,大致分为三部:。第一部分同visualpytune类似,是每个函数占用的时间,其中Incl等同于cumtime, Self等同于tottime。第二部分和第三部分都有很多标签,不同的标签标示从不同的角度来看结果,如图上所以,第三部分的“call graph”展示了该函数的call tree并包含每个子函数的时间百分比,一目了然。
profile针对优化
跟之前的结果对比:

可以看到,优化了差不多3倍。
case 1:a, b = SomeClass(), SomeClass()a.b, b.a = b, acase 2:lst = []lst.append(lst)case 3:self.handler = self.some_func
要解决循环引用,第一个办法是使用弱引用(weakref),第二个是手动解循环引用。
class BaseSlots(object):
__slots__ = ['e', 'f', 'g'] class Slots(BaseSlots):
__slots__ = ['a', 'b', 'c', 'd']
def __init__(self):
self.a = self.b = self.c = self.d = self.e = self.f = self.g = 0 class BaseNoSlots(object):
pass class NoSlots(BaseNoSlots):
def __init__(self):
super(NoSlots,self).__init__()
self.a = self.b = self.c = self.d = self.e = self.f = self.g = 0 def log_time(s):
begin = time.time()
for i in xrange(10000000):
s.a,s.b,s.c,s.d, s.e, s.f, s.g
return time.time() - begin if __name__ == '__main__':
print 'Slots cost', log_time(Slots())
print 'NoSlots cost', log_time(NoSlots())
输出结果:
Slots cost 3.12999987602
NoSlots cost 3.48100018501
python C扩展
beyond CPython
cython
pip install Cython
下面是测试用的python代码,可以看到这两个case都是运算复杂度比较高的例子:
# -*- coding: UTF-8 -*-
def f(x):
return x**2-x def integrate_f(a, b, N):
s = 0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s * dx def main():
import time
begin = time.time()
for i in xrange(10000):
for i in xrange(100):f(10)
print 'call f cost:', time.time() - begin
begin = time.time()
for i in xrange(10000):
integrate_f(1.0, 100.0, 1000)
print 'call integrate_f cost:', time.time() - begin if __name__ == '__main__':
main()
- step1:将文件名(cython_example.py)改为cython_example.pyx
- step2:增加一个setup.py文件,添加一下代码:
from distutils.core import setup
from Cython.Build import cythonize setup(
name = 'cython_example',
ext_modules = cythonize("cython_example.pyx"),
)
- step3:执行python setup.py build_ext --inplace

- step4:执行命令 python -c "import cython_example;cython_example.main()"(注意: 保证当前环境下已经没有 cython_example.py)
def f(double x): # 参数静态类型
return x**2-x def integrate_f(double a, double b, int N):
cdef int i
cdef double s, dx
s = 0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s * dx
然后重新运行上面的第三 四步:结果如下
cdef double f(double x): # 返回值也有类型判断
return x**2-x cdef double integrate_f(double a, double b, int N):
cdef int i
cdef double s, dx
s = 0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s * dx
pypy
在实际项目中测试,pypy大概比cpython要快3到5倍!pypy的性能提升来自JIT Compiler。在前文提到google的Unladen Swallow 项目也是想在CPython中引入JIT,在这个项目失败后,很多开发人员都开始加入pypy的开发和优化。另外pypy占用的内存更少,而且支持stackless,基本等同于协程。
ChangeLog
references
python性能优化的更多相关文章
- Python性能优化(转)
分成两部分:代码优化和工具优化 原文:http://my.oschina.net/xianggao/blog/102600 阅读 Zen of Python,在Python解析器中输入 import ...
- Python性能优化方案
Python性能优化方案 从编码方面入手,代码算法优化,如多重条件判断有限判断先决条件(可看 <改进python的91个建议>) 使用Cython (核心算法, 对性能要求较大的建议使用C ...
- Python性能优化:PyPy、Numba 与 Cython。PyPy的安装及对应pip的安装
性能优化讨论见参考1:大概意思是,PyPy内置JIT,对纯Python项目兼容性极好,几乎可以直接运行并直接获得性能提升:缺点是对很多C语言库支持性不好.Numba是一个库,可以在运行时将Python ...
- Python性能优化的20条建议 (转载)
优化算法时间复杂度 算法的时间复杂度对程序的执行效率影响最大,在Python中可以通过选择合适的数据结构来优化时间复杂度,如list和set查找某一个元素的时间复杂度分别是O(n)和O(1).不同的场 ...
- python 性能优化
1.优化循环 循环之外能做的事不要放在循环内,比如下面的优化可以快一倍 2.使用join合并迭代器中的字符串 join对于累加的方式,有大约5倍的提升 3.使用if is 使用if is True比i ...
- python基础===Python性能优化的20条建议
优化算法时间复杂度 算法的时间复杂度对程序的执行效率影响最大,在Python中可以通过选择合适的数据结构来优化时间复杂度,如list和set查找某一个元素的时间复杂度分别是O(n)和O(1).不同的场 ...
- python性能优化建议
参考: https://segmentfault.com/a/1190000000666603 http://blog.csdn.net/zhoudaxia/article/details/23853 ...
- Python性能优化的20条建议
优化算法时间复杂度 算法的时间复杂度对程序的执行效率影响最大,在Python中可以通过选择合适的数据结构来优化时间复杂度,如list和set查找某一个元素的时间复杂度分别是O(n)和O(1).不同的场 ...
- python性能优化、内存优化、内存泄露;与其他语音比较效率如何?
1.内存泄露:http://www.cnblogs.com/xybaby/p/7491656.html 2.内存优化:http://www.cnblogs.com/xybaby/p/7488216.h ...
随机推荐
- iOS 开源库 之 AFNetWorking 2.x
1. 网络请求的基本知识 2. Get/Post 请求的使用 3. 文件(图片)上传 4. 断点下载 5. 其它使用细节 6. 设计优良的地方
- 段落p元素内的响应式文本布局就靠rem单位实现
<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8&qu ...
- 一张图告诉你什么是Linux distributions...
- CSS设置图片居中的方法
如果是应用了表格,那么设置单元格为align="center"就可以使其中的一切内容居中.如果没有应用表格要想设置图片居中就有点困难了.困难来自不按"常规出牌" ...
- PHP函数 mysql_real_escape_string 与 addslashes 的区别
addslashes 和 mysql_real_escape_string 都是为了使数据安全的插入到数据库中而进行的过滤,那么这两个函数到底是有什么区别呢? 首先,我们还是从PHP手册入手: 手册上 ...
- Linux 系统分区
合理的系统分区,便于后期管理和提高文件的搜索速度 分区格式说明 linux分区不同于windows,linux下硬盘设备名为(IDE硬盘为hdx(x为从a—d)因为IDE硬盘最多四 个,SCSI,SA ...
- Java线程:同步
一 同步的概念 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. MyRunnab ...
- flex stage.width 与stage.stageWidth的区别
flex stage.width 与stage.stageWidth的区别: stage.width 是指舞台上的可视对象占据的尺寸 stage.stageWidth是指舞台设置的尺寸,与舞台上的元件 ...
- AIX上面Oracle数据库相关启动
1,启动停止Oracle实例 (1) su -oracle (2) echo $ORACLE_SID (3) sqlplus /nolog //以不登录到数据库的方式进入sqlplus环境 (4) c ...
- windows 8 安装 oracle 11g 报错:command line option syntax error,type command/? for help
windows 8 安装 oracle 11g 报错:command line option syntax error,type command/? for help 在windows8操作系统上安装 ...