如何记录Python脚本每行的执行时间?

2 投票
1 回答
3064 浏览
提问于 2025-04-18 07:37

我有一个Python脚本,从头到尾逻辑很简单,执行起来也很直接。不过,这个脚本在不同的机器上表现得差别很大,因为它们的环境不一样。所以我想找出代码中哪一行让我遇到了麻烦。

我看到过cProfiler和一些关于记录整个函数执行时间的问题(比如用timeit)。不过,我更想知道的是Python在执行我脚本中的每一行代码时花了多少时间。

这是我的源代码:

import math
result = pow(2,5)
newlist = []
newlist.append(result)
print newlist

我想得到的结果是(行号 - 执行所花的时间,单位是秒):

1 - 0.04
2 - 0.01
3 - 0.06
4 - 0.08
5 - 0.1

编辑:我尝试使用hotshot,这是一个标准库,但我收到了错误信息。

我运行的源代码是:

import hotshot
import hotshot.stats

logfile = r"C:\testlog.prof"
prof_obj = hotshot.Profile(logfile,lineevents=True,linetimings=False)
prof_obj.start()
a = 1000
b = 2000
c = a + b
print c
prof_obj.stop()
prof_obj.close()

stats_obj = hotshot.stats.load(logfile) #getting error on this line *
stats_obj.strip_dirs()
stats_obj.sort_stats('time', 'calls')
stats_obj.print_stats(20)

*     for event in log:
  File "C:\Python27\ArcGIS10.2\Lib\hotshot\log.py", line 115, in next
    filename, firstlineno, funcname = self._stack[-1]
IndexError: list index out of range

编辑:我在《Python Essential Reference》这本书中找到了另一个使用hotshot的例子。

import hotshot
import hotshot.stats

def function_to_call():
    print "AA"
    print "BB"

logfile = r"C:\testlog.prof"
prof_obj = hotshot.Profile(logfile,lineevents=True,linetimings=True)
prof_obj.runcall(function_to_call)
prof_obj.close()

stats_obj = hotshot.stats.load(logfile)
stats_obj.sort_stats('time', 'calls')
stats_obj.print_stats()

不过,这个例子并没有给我每行代码的执行信息,只是每个函数调用的执行时间:

5 function calls in 0.012 seconds

   Ordered by: internal time, call count

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        4    0.012    0.003    0.012    0.003 <string>:6(write)
        1    0.000    0.000    0.012    0.012 c:\gis\temp\simple_hotshot.py:11(function_to_call)
        0    0.000             0.000          profile:0(profiler)

1 个回答

4

有一个叫做 line profiler模块 的东西,可能正好符合你的需求。它还有一些很方便的装饰器,可以用在你想要逐行分析的函数上。你可以在 这里 查看相关文档。

另外,你也可以看看 hotshot。看起来你可以设置 linetimings 参数来获取你想要的信息。不过,我不太确定 hotshot 在未来的版本中是否会继续被支持。

撰写回答