python 的线路分析器中的总时间很奇怪
Total time in python's line profiler is strange
这是我的 insertion.py:
import random
#@profile
def insertion_sort(l):
for j in range(1, len(l)):
k = l[j]
i = j - 1
while i >= 0 and l[i] > k:
l[i + 1] = l[i]
i -= 1
l[i + 1] = k
if __name__ == '__main__':
l = range(5000)
random.shuffle(l)
insertion_sort(l)
当我 运行 time python insertion.py
时,我得到:
real 0m0.823s
user 0m0.818s
sys 0m0.004s
但是当我取消注释配置文件装饰器和 运行: kernprof -l -v insertion.py
, 我得到:
Wrote profile results to insertion.py.lprof
Timer unit: 1e-06 s
Total time: 7.25971 s
File: insertion.py
Function: insertion_sort at line 4
Line # Hits Time Per Hit % Time Line Contents
==============================================================
4 @profile
5 def insertion_sort(l):
6 5000 2110 0.4 0.0 for j in range(1, len(l)):
7 4999 1929 0.4 0.0 k = l[j]
8 4999 1719 0.3 0.0 i = j - 1
9 6211255 2695158 0.4 37.1 while i >= 0 and l[i] > k:
10 6206256 2396675 0.4 33.0 l[i + 1] = l[i]
11 6206256 2160158 0.3 29.8 i -= 1
12 4999 1959 0.4 0.0 l[i + 1] = k
我的问题是为什么线路分析器的总时间比系统时间大很多?我认为行分析器的 "Total time" 描述了用 @profile 装饰的函数 运行ning 的时间。在我看来,time
的输出应该更大或至少接近线性分析器。我对结果的解释有误吗?线路分析器是否将自己的时间添加到 "Total time"?
我的结果表明 ContextualProfile
adds almost no overhead in this case, but the LineProfiler
增加了大量开销。
这并不奇怪,因为 LineProfiler
执行 a bunch of code for every line。因此,以前是简单赋值或简单比较的行现在包括几个比较、函数调用和数据结构。
在我的结果中,LineProfiler
开销可以估计为每行 527 到 615 纳秒,计算方法是将总时间 (11.2287s) 除以命中数 (5000 + 4999 + 4999 + 6081512 + 6076513 + 6076513 + 4999 = 18254535 ≅ 18M),然后减去另一个分析器的总时间除以相同的命中数。同样,这只是对开销的粗略估计。
完整的输出如下:
$ time python2 insertion.py
real 0m1.561s
user 0m1.548s
sys 0m0.012s
$ sed -i 's/^#@profile$/@profile/' insertion.py
$ kernprof -b -v insertion.py
Wrote profile results to insertion.py.prof
5 function calls in 1.619 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 1.619 1.619 1.619 1.619 insertion.py:5(insertion_sort)
1 0.000 0.000 0.000 0.000 kernprof.py:63(disable_by_count)
1 0.000 0.000 0.000 0.000 {len}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {range}
$ kernprof -b -l -v insertion.py
Wrote profile results to insertion.py.lprof
Timer unit: 1e-06 s
Total time: 11.2287 s
File: insertion.py
Function: insertion_sort at line 5
Line # Hits Time Per Hit % Time Line Contents
==============================================================
5 @profile
6 def insertion_sort(l):
7 5000 2819 0.6 0.0 for j in range(1, len(l)):
8 4999 2870 0.6 0.0 k = l[j]
9 4999 2792 0.6 0.0 i = j - 1
10 6081512 3871421 0.6 34.5 while i >= 0 and l[i] > k:
11 6076513 4014703 0.7 35.8 l[i + 1] = l[i]
12 6076513 3330633 0.5 29.7 i -= 1
13 4999 3425 0.7 0.0 l[i + 1] = k
这是我的 insertion.py:
import random
#@profile
def insertion_sort(l):
for j in range(1, len(l)):
k = l[j]
i = j - 1
while i >= 0 and l[i] > k:
l[i + 1] = l[i]
i -= 1
l[i + 1] = k
if __name__ == '__main__':
l = range(5000)
random.shuffle(l)
insertion_sort(l)
当我 运行 time python insertion.py
时,我得到:
real 0m0.823s
user 0m0.818s
sys 0m0.004s
但是当我取消注释配置文件装饰器和 运行: kernprof -l -v insertion.py
, 我得到:
Wrote profile results to insertion.py.lprof
Timer unit: 1e-06 s
Total time: 7.25971 s
File: insertion.py
Function: insertion_sort at line 4
Line # Hits Time Per Hit % Time Line Contents
==============================================================
4 @profile
5 def insertion_sort(l):
6 5000 2110 0.4 0.0 for j in range(1, len(l)):
7 4999 1929 0.4 0.0 k = l[j]
8 4999 1719 0.3 0.0 i = j - 1
9 6211255 2695158 0.4 37.1 while i >= 0 and l[i] > k:
10 6206256 2396675 0.4 33.0 l[i + 1] = l[i]
11 6206256 2160158 0.3 29.8 i -= 1
12 4999 1959 0.4 0.0 l[i + 1] = k
我的问题是为什么线路分析器的总时间比系统时间大很多?我认为行分析器的 "Total time" 描述了用 @profile 装饰的函数 运行ning 的时间。在我看来,time
的输出应该更大或至少接近线性分析器。我对结果的解释有误吗?线路分析器是否将自己的时间添加到 "Total time"?
我的结果表明 ContextualProfile
adds almost no overhead in this case, but the LineProfiler
增加了大量开销。
这并不奇怪,因为 LineProfiler
执行 a bunch of code for every line。因此,以前是简单赋值或简单比较的行现在包括几个比较、函数调用和数据结构。
在我的结果中,LineProfiler
开销可以估计为每行 527 到 615 纳秒,计算方法是将总时间 (11.2287s) 除以命中数 (5000 + 4999 + 4999 + 6081512 + 6076513 + 6076513 + 4999 = 18254535 ≅ 18M),然后减去另一个分析器的总时间除以相同的命中数。同样,这只是对开销的粗略估计。
完整的输出如下:
$ time python2 insertion.py
real 0m1.561s
user 0m1.548s
sys 0m0.012s
$ sed -i 's/^#@profile$/@profile/' insertion.py
$ kernprof -b -v insertion.py
Wrote profile results to insertion.py.prof
5 function calls in 1.619 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 1.619 1.619 1.619 1.619 insertion.py:5(insertion_sort)
1 0.000 0.000 0.000 0.000 kernprof.py:63(disable_by_count)
1 0.000 0.000 0.000 0.000 {len}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {range}
$ kernprof -b -l -v insertion.py
Wrote profile results to insertion.py.lprof
Timer unit: 1e-06 s
Total time: 11.2287 s
File: insertion.py
Function: insertion_sort at line 5
Line # Hits Time Per Hit % Time Line Contents
==============================================================
5 @profile
6 def insertion_sort(l):
7 5000 2819 0.6 0.0 for j in range(1, len(l)):
8 4999 2870 0.6 0.0 k = l[j]
9 4999 2792 0.6 0.0 i = j - 1
10 6081512 3871421 0.6 34.5 while i >= 0 and l[i] > k:
11 6076513 4014703 0.7 35.8 l[i + 1] = l[i]
12 6076513 3330633 0.5 29.7 i -= 1
13 4999 3425 0.7 0.0 l[i + 1] = k