为啥 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=&lt;default timer&gt;, number=1000000)docs.python.org/2/library/timeit.html 嗯,也许你是对的。我使用魔法%timeit,它确实可以扩展。即使代码运行了 0.01 秒,您也要等待将近 3 个小时才能完成该测试。我看看缩放是不是专门限制在魔术方法上 【参考方案1】:

timeit 的目的是获取函数的吞吐量,这将始终需要代码运行多次以淡出边缘情况并给出良好的平均值。

而另一方面,cProfile 用于分析函数堆栈的每个子调用,以揭开函数内部发生的所有魔法的神秘面纱。

timeit 会告诉您需要进行一些优化才能运行,而cProfile 会指出正确的方向,告诉您堆栈的哪个微小部分占用了您的周转时间。

【讨论】:

以上是关于为啥 cProfile 只运行一次代码?的主要内容,如果未能解决你的问题,请参考以下文章

如何计算几个 cProfile 结果的平均结果?

为啥 cProfile 会导致函数返回不同的值?

cProfile命令行如何减少输出

为啥 Makefile 目标依赖于两个目标,但只运行一次?

为啥我的函数在每次页面加载时只运行一次?

在 Python 中的文件列表上运行 cProfile