为啥 cProfile 只运行一次代码?
Posted
技术标签:
【中文标题】为啥 cProfile 只运行一次代码?【英文标题】:Why does cProfile only run through the code once?为什么 cProfile 只运行一次代码? 【发布时间】:2019-10-28 19:44:03 【问题描述】:另一方面,timeit
运行代码 1,000,000 次以获得与其他代码的合理渐近比较。 cProfile
只运行一次代码,结果只有 3 位小数(0.000),不足以了解全貌。
你会得到这样无用的结果:
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 built-in method builtins.exec
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 a.py:27(function)
1 0.000 0.000 0.000 0.000 method 'disable' of '_lsprof.Profiler' objects
【问题讨论】:
您最好使用line_profiler
。但是,timeit
用于小型 sn-ps,cProfile
只是表明您关注的特定代码与整个程序无关
您确实提出了一个很好的观点,在大型程序中运行默认 timeit
是不可能的。
另外,默认 timeit
将不会通过通用代码运行 100 万次。除非指定运行次数,否则它将动态扩展实际运行的次数。如果你在这段代码上默认运行 100 万次,这意味着它的速度快得离谱。如果它只不过是一些定义而根本没有实际计算,我不会感到惊讶。这与您的 cProfile 0 相关
@roganjosh 动态扩展是什么意思?文档清楚地说,runs 参数的number
的默认参数是 1mil:timeit.timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000)
docs.python.org/2/library/timeit.html
嗯,也许你是对的。我使用魔法%timeit
,它确实可以扩展。即使代码运行了 0.01 秒,您也要等待将近 3 个小时才能完成该测试。我看看缩放是不是专门限制在魔术方法上
【参考方案1】:
timeit
的目的是获取函数的吞吐量,这将始终需要代码运行多次以淡出边缘情况并给出良好的平均值。
而另一方面,cProfile
用于分析函数堆栈的每个子调用,以揭开函数内部发生的所有魔法的神秘面纱。
timeit
会告诉您需要进行一些优化才能运行,而cProfile
会指出正确的方向,告诉您堆栈的哪个微小部分占用了您的周转时间。
【讨论】:
以上是关于为啥 cProfile 只运行一次代码?的主要内容,如果未能解决你的问题,请参考以下文章