我在我的代码中第一次使用cProfiler
,并试图理解它的结果。我在这里发布了一个玩具代码来说明我的问题。有两个循环,一个在另一个里面,我不知道分析器计算的时间是多少。
prof=cProfile.Profile()
tmax=100
t=0
dt=0.1
n=10000
prof.enable()
while t<tmax:
B=[]
t=t+dt
for j in range(n):
val=dt*j
B.append(val)
B=sorted(B)
B=np.array(B)
C=B*cos(dt)
mini=min(C[C>0])
if mini==0:
mini=1
prof.disable()
prof.print_stats()
输出:
10014023 function calls in 7.323 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <ipython-input-59-761fc8d7f6eb>:22(<module>)
1 4.316 4.316 7.322 7.322 <ipython-input-59-761fc8d7f6eb>:8(<module>)
2 0.000 0.000 0.000 0.000 codeop.py:140(__call__)
2 0.000 0.000 0.000 0.000 hooks.py:139(__call__)
2 0.000 0.000 0.000 0.000 hooks.py:204(pre_run_code_hook)
2 0.000 0.000 0.000 0.000 interactiveshell.py:1067(user_global_ns)
2 0.000 0.000 7.322 3.661 interactiveshell.py:2852(run_code)
2 0.000 0.000 0.000 0.000 ipstruct.py:125(__getattr__)
2 0.000 0.000 0.000 0.000 {built-in method builtins.compile}
2 0.000 0.000 7.322 3.661 {built-in method builtins.exec}
1001 0.996 0.001 0.996 0.001 {built-in method builtins.min}
1001 0.119 0.000 0.119 0.000 {built-in method builtins.sorted}
1001 0.003 0.000 0.003 0.000 {built-in method math.cos}
1001 0.982 0.001 0.982 0.001 {built-in method numpy.array}
10010000 0.906 0.000 0.906 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
考虑如果我将分析器如下所示会发生什么:
prof=cProfile.Profile()
tmax=100
t=0
dt=0.1
n=10000
while t<tmax:
prof.enable()
B=[]
t=t+dt
for j in range(n):
val=dt*j
B.append(val)
B=sorted(B)
B=np.array(B)
C=B*cos(dt)
mini=min(C[C>0])
if mini==0:
print("Zero")
prof.disable()
prof.print_stats()
输出:
10015005 function calls in 3.032 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1001 1.014 0.001 1.014 0.001 {built-in method builtins.min}
1001 0.120 0.000 0.120 0.000 {built-in method builtins.sorted}
1001 0.004 0.000 0.004 0.000 {built-in method math.cos}
1001 0.963 0.001 0.963 0.001 {built-in method numpy.array}
10010000 0.930 0.000 0.930 0.000 {method 'append' of 'list' objects}
1001 0.001 0.000 0.001 0.000 {method 'disable' of '_lsprof.Profiler' objects}
在后一种情况下,如果分析器只显示最后一次while循环迭代的时间,那么它仍然没有意义,因为如果一次迭代需要3秒,那么只有2次迭代,总时间约为7秒,但会有更多的迭代发生(大约1000次)
这是怎么回事?
我注意到当分析器被用来分析顺序代码而不是函数时,它似乎没有给出正确的答案。
例如这里的时间和分析器的时间是非常不同的。
...
s = time.time()
prof.enable()
#line1
#line2
...
#lineN
e = time.time()
prof.disable()
,但这给出了正确的结果。当你输入line1…函数foo()
中的亚麻...
s = time.time()
prof.enable()
foo()
e = time.time()
prof.disable()
...
所以编辑你的代码,把你想要分析的代码放在一个函数中,然后使用分析器。
根据报告的ncalls,很明显后一种情况显示了while循环所有1001次迭代的累积信息(由于t += 0.1的浮点不精度,它是1001而不是1000)
前者与后者的区别在于前者的例子花了4秒以上的时间来处理动作<ipython-input-59-761fc8d7f6eb>:8(<module>)
看起来您是在解释器中运行这些测试。您是否尝试过将相同的代码作为脚本运行?