Python 定位程序性能瓶颈
对代码优化的前提是需要了解性能瓶颈在什么地方,程序运行的主要时间是消耗在哪里,对于比较复杂的代码可以借助一些工具来定位,python 内置了丰富的性能分析工具,如 profile, cProfile 与 hotshot 等。其中 Profiler 是 python 自带的一组程序,能够描述程序运行时候的性能,并提供各种统计帮助用户定位程序的性能瓶颈。Python 标准模块提供三种 profilers:cProfile, profile 以及 hotshot。
profile
profile 的使用非常简单,只需要在使用之前进行 import 即可。具体实例如下:
import profile
def profileTest():
for i in range(20000):
sent = "a sentence for measuring a find function"
print(sent[16:])
if __name__ == "__main__":
profile.run("profileTest()")
运行结果:
20005 function calls in 0.047 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.047 0.047 :0(exec)
20000 0.031 0.000 0.031 0.000 :0(print)
1 0.000 0.000 0.000 0.000 :0(setprofile)
1 0.000 0.000 0.047 0.047 <string>:1(<module>)
1 0.000 0.000 0.047 0.047 profile:0(profileTest())
0 0.000 0.000 profile:0(profiler)
1 0.016 0.016 0.047 0.047 writefile.py:38(profileTest)
其中输出每列的具体解释如下:
- ncalls:表示函数调用的次数;
- tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;
- percall:(第一个 percall)等于 tottime/ncalls;
- cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;
- percall:(第二个 percall)即函数运行一次的平均时间,等于 cumtime/ncalls;
- filename:lineno(function):每个函数调用的具体信息;
如果需要将输出以日志的形式保存,只需要在调用的时候加入另外一个参数。如 profile.run("profileTest()", "testprof")
。
pstats
对于 profile
的剖析数据,如果以二进制文件的时候保存结果的时候,可以通过 pstats 模块进行文本报表分析,它支持多种形式的报表输出,是文本界面下一个较为实用的工具。使用非常简单:
import pstats
p = pstats.Stats('testprof')
p.sort_stats("name").print_stats()
显示结果类似上文。
其中 sort_stats() 方法能够对剖分数据进行排序, 可以接受多个排序字段,如 sort_stats('name', 'file') 将首先按照函数名称进行排序,然后再按照文件名进行排序。常见的排序字段有 calls( 被调用的次数 ),time(函数内部运行时间),cumulative(运行的总时间)等。此外 pstats 也提供了命令行交互工具,执行 python – m pstats 后可以通过 help 了解更多使用方式。
对于大型应用程序,如果能够将性能分析的结果以图形的方式呈现,将会非常实用和直观,常见的可视化工具有 Gprof2Dot,visualpytune,KCacheGrind 等。
https://www.ibm.com/developerworks/cn/linux/l-cn-python-optim/index.html
使用 timeit
from timeit import timeit
import re
def find(string, text):
if string.find(text) > -1:
pass
def re_find(string, text):
if re.match(text, string):
pass
def best_find(string, text):
if text in string:
pass
print timeit("find(string, text)", "from __main__ import find; string='lookforme'; text='look'")
print timeit("re_find(string, text)", "from __main__ import re_find; string='lookforme'; text='look'")
print timeit("best_find(string, text)", "from __main__ import best_find; string='lookforme'; text='look'")
运行结果:
0.25795071095385774
0.8158124762311382
0.10521701806419292
因此,字符串搜索,应该使用 in 运算符,因为它更容易阅读,但因为它也更快。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com
文章标题:Python 定位程序性能瓶颈
文章字数:913
本文作者:Bin
发布时间:2018-08-09, 22:57:22
最后更新:2019-08-06, 00:07:35
原始链接:http://coolview.github.io/2018/08/09/Python/Python%20%E5%AE%9A%E4%BD%8D%E7%A8%8B%E5%BA%8F%E6%80%A7%E8%83%BD%E7%93%B6%E9%A2%88/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。