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 ...
随机推荐
- 1.1.3.托管对象上下文(Core Data 应用程序实践指南)
管理托管对象的生命周期(lifecycle).还有其它功能:faulting.变更追踪(change tracking).验证(validation)等. faulting:只把用到的那一部分数据从持 ...
- EverNote剪藏插件安装问题
安装EverNote印象笔记的剪藏插件时出现插件不能使用的问题,可以采用如下的方法(可以参考知乎的解决办法:https://www.zhihu.com/question/29875051) (下载地址 ...
- PHP导入导出Excel方法
看到这篇文章的时候,很是惊讶原作者的耐心,虽然我们在平时用的也 有一些,但没有作者列出来的全,写excel的时候,我用过pear的库,也用过pack压包的头,同样那些利用smarty等作的简单替换xm ...
- js原生设计模式——3简单工厂模式\简单工厂模式封装简单对象
1.Factory基本写法 <!DOCTYPE html><html lang="en"><head> <meta charset= ...
- 使用 GitHub, Jekyll 打造自己的免费独立博客
使用 GitHub, Jekyll 打造自己的免费独立博客 GitHub是一个代码托管网站,现在很多开源项目都放在GitHub上. 利用GitHub,可以让全球各地的程序员们一起协作开发.GitHub ...
- requests从api中获取数据并存放到mysql中
python的requests库是一个非常强大的库,requests的安装方法十分简单,用: pip install requests 即可安装requests,安装成功后: import reque ...
- Wireshark网络抓包(二)——过滤器
一.捕获过滤器 选中捕获选项后,就会弹出下面这个框,在红色输入框中就可以编写过滤规则. 1)捕获单个IP地址 2)捕获IP地址范围 3)捕获广播或多播地址 4)捕获MAC地址 5)捕获所有端口号 6) ...
- 使用PMD进行代码审查
很久没写博客了,自从上次写的设计模式的博客被不知名的鹳狸猿下架了一次之后兴趣大减,那时候就没什么兴致写博客了,但是这段时间还没有停下来,最近也在研究一些其他的东西,目前有点想做点东西的打算,但好像也没 ...
- POJ 1308 Is It A Tree?--题解报告
Is It A Tree? Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 31092 Accepted: 10549 D ...
- Raid类型
raid0:两块磁盘同时写入raid1:一块磁盘写入,另一块磁盘做备份,利用率50%raid5:两块磁盘同时写入两块磁盘都有内容,第三块磁盘做效应,n/n-1的利用率raid6:四块磁盘两块磁盘做存储 ...