1.可视化逐行代码运行时间工具vprof:
https://github.com/nvdv/vprof
安装:
sudo pip3 install vprof
然后直接用它运行代码:
vprof -c h test.py
h会让它根据每行代码的运行时间附上热图。
需要带输入时:
vprof -c cmh "testscript.py --foo --bar"
2.强烈推荐:cProfile+gprof2dot 图表化各部分运行时间:
https://github.com/jrfonseca/gprof2dot
sudo pip3 install gprof2dot
使用方法,先用cProfile生成分析报告:
python3 -m cProfile -o output.pstats test.py
再用gprof2dot把图画出来:
gprof2dot -f pstats output.pstats | dot -Tpng -o output.png
3.用上下文管理器测量部分代码运行时间:
from time import clock
class Timer(object):
def __init__(self, verbose=False):
self.verbose = verbose
def __enter__(self):
self.start = clock()
return self
def __exit__(self, *args):
self.end = clock()
self.secs = self.end - self.start
self.msecs = self.secs * 1000 # millisecs
if self.verbose:
print 'elapsed time: %f ms' % self.msecs
if __name__ == "__main__":
with Timer() as t:
replace_str = ""
for i, char in enumerate(orignal_str * 10000):
c = char if char != " " else "-"
replace_str += c
print t.secs
4.优化小方法:
1.使用 cProfile, cStringIO 和 cPickle等用c实现相同功能(分别对应profile, StringIO, pickle)的包
2.使用c扩展:
目前主要有CPython(python最常见的实现的方式)原生API, ctypes,Cython,cffi三种方式,它们的作用是使得Python程序可以调用由C编译成的动态链接库,其特点分别是:
CPython原生API: 通过引入Python.h头文件,对应的C程序中可以直接使用Python的数据结构。实现过程相对繁琐,但是有比较大的适用范围。
ctypes: 通常用于封装(wrap)C程序,让纯Python程序调用动态链接库(Windows中的dll或Unix中的so文件)中的函数。如果想要在python中使用已经有C类库,使用ctypes是很好的选择,有一些基准测试下,python+ctypes是性能最好的方式。
Cython: Cython是CPython的超集,用于简化编写C扩展的过程。Cython的优点是语法简洁,可以很好地兼容numpy等包含大量C扩展的库。Cython的使得场景一般是针对项目中某个算法或过程的优化。在某些测试中,可以有几百倍的性能提升。
cffi: cffi的就是ctypes在pypy(详见下文)中的实现,同进也兼容CPython。cffi提供了在python使用C类库的方式,可以直接在python代码中编写C代码,同时支持链接到已有的C类库。使用这些优化方式一般是针对已有项目性能瓶颈模块的优化,可以在少量改动原有项目的情况下大幅度地提高整个程序的运行效率。
3.并行编程 multiprocessing
4.大杀器PyPy:
PyPy是用RPython(CPython的子集)实现的Python,使用了Just-in-Time(JIT)编译器,即动态编译器,与静态编译器(如gcc,javac等)不同,它是利用程序运行的过程的数据进行优化。如果python程序中含有C扩展(非cffi的方式),JIT的优化效果会大打折扣,甚至比CPython慢(比Numpy)。所以在PyPy中最好用纯Python或使用cffi扩展。
5.CUDA编程