背景
之前再effective python 58章了解了性能分析的方法,
最近刚好用到工作上了,是一个很不错的方法,今天
特意介绍下cProfile与pstats
代码
def insertion_sort(data):
result = []
for value in data:
insert_value(result, value)
return result
def insert_value(array, value):
for i, existing in enumerate(array):
if existing > value:
array.insert(i, value)
return
array.append(value)
if __name__ == '__main__':
from random import randint
from cProfile import Profile
from pstats import Stats
max_size = 10 ** 4
data = [randint(0, max_size) for _ in range(max_size)]
profiler = Profile()
profiler.runcall(insertion_sort, data)
stats = Stats(profiler)
stats.strip_dirs()
stats.sort_stats('cumulative') # 根据累计时间排序
# stats.print_callers()
stats.print_stats(2) # 输出头两个 不指定数量则输出所有
可以看到统计输出:
Ordered by: cumulative time
List reduced from 5 to 2 due to restriction <2>
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.011 0.011 2.009 2.009 detail_total.py:4(insertion_sort)
10000 1.971 0.000 1.998 0.000 detail_total.py:11(insert_value)
# 结果
可以清晰的统计分许 耗时的函数 可以大致定位方向
还有一个分析函数内部每行的执行时间的方法
pip install line_profiler
import line_profiler
import sys
def test(a):
for i in range(1000):
a+=1
prof = line_profiler.LineProfiler(test)
prof.enable() # 开始性能分析
test(3)
prof.disable() # 停止性能分析
prof.print_stats(sys.stdout)
Timer unit: 1e-06 s
Total time: 0.000802 s
File: /home/liuhu001/temp/effective_python/58perfomance/time_count/profile_line.py
Function: test at line 6
Line # Hits Time Per Hit % Time Line Contents
==============================================================
6 def test(a):
7 1001 352.0 0.4 43.9 for i in range(1000):
8 1000 450.0 0.5 56.1 a+=1
大部分情况下 很少到需要性能优化这一步,一旦需要,则可以借鉴工具,
快速定位,并优化参考文章
cprofile