python - 如何计算几个 cProfile 结果的平均结果?
问题描述
而不是像这样只运行一次配置文件:
import cProfile
def do_heavy_lifting():
for i in range(100):
print('hello')
profiller = cProfile.Profile()
profiller.enable()
do_heavy_lifting()
profiller.disable()
profiller.print_stats(sort='time')
配置文件结果如下所示:
502 function calls in 0.000 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
100 0.000 0.000 0.000 0.000 {built-in method builtins.print}
200 0.000 0.000 0.000 0.000 cp1252.py:18(encode)
200 0.000 0.000 0.000 0.000 {built-in method _codecs.charmap_encode}
1 0.000 0.000 0.000 0.000 test.py:2(do_heavy_lifting)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
我想运行几次并打印平均结果,以获得更好的精度。
这是我想到的初始脚本配方:
import cProfile
def do_heavy_lifting():
for i in range(100):
print('hello')
def best_of_profillings(target_profile_function, count):
profile_results = []
for index in range(count):
profiller = cProfile.Profile()
profiller.enable()
target_profile_function()
profiller.disable()
profile_results.append(profiller)
profile_results /= count
return profile_results
heavy_lifting_result = best_of_profillings(do_heavy_lifting, 10)
heavy_lifting_result.print_stats(sort='time')
运行后,它应该像第一个版本一样显示结果,但不同之处在于它们是几次运行的平均值,而不是运行一次。
草稿脚本仍然缺少profile_results /= count
在所有迭代之后,我将获得所有计算结果并创建平均结果并将其始终显示在屏幕上的部分:
502 function calls in 0.000 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
100 0.000 0.000 0.000 0.000 {built-in method builtins.print}
200 0.000 0.000 0.000 0.000 cp1252.py:18(encode)
200 0.000 0.000 0.000 0.000 {built-in method _codecs.charmap_encode}
1 0.000 0.000 0.000 0.000 test.py:2(do_heavy_lifting)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
解决方案
我设法使用函数创建了以下代码average()
。我打开了实现pstats
并观察到有一个函数调用Stats.add()
,它似乎只是将结果连接到当前对象中: https ://docs.python.org/3.7/library/profile.html#pstats.Stats.add
import io
import pstats
import cProfile
def do_heavy_lifting():
for i in range(100):
print('hello')
def average(stats, count):
stats.total_calls /= count
stats.prim_calls /= count
stats.total_tt /= count
for func, source in stats.stats.items():
cc, nc, tt, ct, callers = source
stats.stats[func] = ( cc/count, nc/count, tt/count, ct/count, callers )
return stats
def best_of_profillings(target_profile_function, count):
output_stream = io.StringIO()
profiller_status = pstats.Stats( stream=output_stream )
for index in range(count):
profiller = cProfile.Profile()
profiller.enable()
target_profile_function()
profiller.disable()
profiller_status.add( profiller )
print( 'Profiled', '%.3f' % profiller_status.total_tt, 'seconds at', index,
'for', target_profile_function.__name__, flush=True )
average( profiller_status, count )
profiller_status.sort_stats( "time" )
profiller_status.print_stats()
return "\nProfile results for %s\n%s" % (
target_profile_function.__name__, output_stream.getvalue() )
heavy_lifting_result = best_of_profillings( do_heavy_lifting, 10 )
print( heavy_lifting_result )
结果:
Profile results for do_heavy_lifting
102.0 function calls in 0.001 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
100.0 0.001 0.000 0.001 0.000 {built-in method builtins.print}
1.0 0.000 0.000 0.001 0.001 D:\test.py:5(do_heavy_lifting)
1.0 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
推荐阅读
- java - 要么重新中断此方法,要么在声纳中重新抛出“InterruptedException 问题
- android - 从通道对象获取最后一条消息时的空对象引用 - Twilio 可编程聊天 Android SDK
- java - 从银行转账中获取日期
- java - 如何在我的 java bean 中获取嵌套对象的值?
- java - 在 SQlite 数据库中添加新行时,所有列表行都会在自定义列表视图中重复,然后是列表视图
- sailpoint - 账户名显示???在 Sailpoint 中,而不是帐户名称
- blueprism - 只是为了确认蓝棱镜间谍活动
- java - 如何使用 onCreate 外部的 onBackPressed 停止 onCreate 内部的处理程序?
- javascript - 如何向 taginput 元素添加验证?
- google-apps-script - Google 电子表格自定义脚本参考