下面是一段利用python装饰器进行计时的代码(侵删,出处忘了):
def timerfunc(func):
"""
A timer decorator
"""
def function_timer(*args, **kwargs):
"""
A nested function for timing other functions
"""
start = time.time()
value = func(*args, **kwargs)
end = time.time()
runtime = end - start
msg = "The runtime for {func} took {time} seconds to complete"
print(msg.format(func=func.__name__, time=runtime))
return value
return function_timer
利用装饰器计时是比较优雅的,但是也有下图的问题。
有的函数,我们明知它是核心逻辑,但因为调用次数多、每次耗时短,而不能精确测量;此外,记录数过多,不利于分析。
cProfile可以解决上一段提到的问题,它会统计调用次数和总耗时,可以将结果按总耗时排序。代码如下:
from cProfile import Profile
import io
import pstats
prof = Profile()
prof.enable()
#do something
prof.create_stats()
s = io.StringIO()
ps = pstats.Stats(prof, stream=s).sort_stats(pstats.SortKey.CUMULATIVE)
ps.print_stats()
fp = open('profile.txt', 'w')
fp.write(s.getvalue())
fp.close()
说实话,cProfile我也不太满意,即使依据耗时排序,依然会有很多无关内容。我只想显示其中的用户自定义的底层函数的耗时。为此,我觉得可以将cProfile的结果输出到文件,再做后续处理。
可以先将所有想测试的函数名称放在一个list里;
然后遍历上一步中profile.txt中的每一行,检查是否是想测试的函数;
若是则输出。