正如我在评论中提到的那样,当您无法
cProfile在外部工作时,通常可以在内部使用它。没那么难。
例如,当我
-m cProfile在Python 2.7中运行时,实际上可以得到与您相同的结果。但是当我手动检测您的示例程序时:
import fileinputimport cProfilepr = cProfile.Profile()pr.enable()for line in fileinput.input(): for i in range(10): y = int(line.strip()) + int(line.strip())pr.disable()pr.print_stats(sort='time')
……这就是我得到的:
22002533 function calls (22001691 primitive calls) in 3.352 seconds Ordered by: internal time ncalls tottime percall cumtime percall filename:lineno(function) 20000000 2.326 0.000 2.326 0.000 {method 'strip' of 'str' objects} 1000001 0.646 0.000 0.700 0.000 fileinput.py:243(next) 1000000 0.325 0.000 0.325 0.000 {range} 842 0.042 0.000 0.042 0.000 {method 'readlines' of 'file' objects} 1684/842 0.013 0.000 0.055 0.000 fileinput.py:292(readline) 1 0.000 0.000 0.000 0.000 fileinput.py:197(__init__) 1 0.000 0.000 0.000 0.000 fileinput.py:91(input) 1 0.000 0.000 0.000 0.000 {isinstance} 1 0.000 0.000 0.000 0.000 fileinput.py:266(nextfile) 1 0.000 0.000 0.000 0.000 fileinput.py:240(__iter__) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}这有用得多:它告诉您可能已经期望的东西,其中一半以上的时间都花在打电话上
str.strip()。
另外,请注意,如果您无法编辑包含要分析的代码的文件(
mwe.py),则始终可以执行以下操作:
import cProfilepr = cProfile.Profile()pr.enable()import mwepr.disable()pr.print_stats(sort='time')
即使这样也不总是可行。
exit()例如,如果您的程序调用,则必须使用
try:/
finally:包装和/或
atexit。它称为
os._exit()或segfaults,您可能已经完全陷入困境。但这不是很常见。
但是,我后来发现了一些事情:如果将所有代码移出全局范围,
-m cProfile似乎至少在这种情况下有效。例如:
import fileinputdef f(): for line in fileinput.input(): for i in range(10): y = int(line.strip()) + int(line.strip())f()
现在,来自的输出
-m cProfile包括:
2000000 4.819 0.000 4.819 0.000:0(条)100001 0.288 0.000 0.295 0.000
fileinput.py:243(下一个)
我不知道为什么这也会使速度慢两倍…也许这只是缓存效果;从我上次运行到现在已经过了几分钟,并且我之间进行了很多网络浏览。但这并不重要,重要的是大部分时间都在合理的地方进行充电。
但是,如果我更改此设置以将外循环移动到全局级别,并且仅将其主体移动到函数中,则大多数时候又会消失。
另一种选择,除非万不得已,否则我不会建议…
我注意到,如果我使用配置文件而不是cProfile,则它在内部和外部均可工作,从而为正确的呼叫收取时间。但是,这些通话速度也要慢5倍左右。而且似乎还会有10秒钟的持续开销(
importprofile如果在内部使用,则需要付费,如果在外部使用,则在第1行上需要付费)。因此,要发现这
split占用了我70%的时间,而不是等待4秒并执行2.326
/ 3.352,我必须等待27秒,并执行10.93 /(26.34-10.01)。没什么好玩的…
最后一件事:使用CPython 3.4开发人员构建时,我得到相同的结果-在内部使用时正确的结果,在外部使用时一切都记在第一行代码中。但是PyPy 2.2 /2.7.3和PyPy3 2.1b1 / 3.2.3似乎都给我正确的结果
-mcProfile。这可能仅仅意味着PyPy
cProfile被伪造了,
profile因为纯Python代码足够快。
无论如何,如果有人可以弄清楚/解释为什么
-m cProfile它不起作用,那将是很棒的……但是,否则,这通常是一个非常好的解决方法。



