为什么 python 探查器给出相互矛盾的结果?
Why python profiler gives contradicting results?
玩一下python分析器,看下面的代码:
>>> def testa():
... a = []
... pr = cProfile.Profile()
... pr.enable()
... for i in range(100000):
... a.append(1)
... pr.disable()
... pr.print_stats()
>>> def testb():
... a = []
... pr = cProfile.Profile()
... pr.enable()
... for i in range(100000):
... a = a + [1]
... pr.disable()
... pr.print_stats()
基本上我想看看 append
方法与自连接列表之间的结果,我认为自连接会更昂贵,当我调用 testb
实际用了更长时间才完成。
但是探查器的结果是错误的?
>>> testa()
100002 function calls in 0.006 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
100000 0.005 0.000 0.005 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.001 0.001 0.001 0.001 {range}
>>> testb()
2 function calls in 0.001 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.001 0.001 0.001 0.001 {range}
Python 必须每次查找列表的 "append" 方法的含义。语言是非常动态的,方法可以随时改变。要改进这一点,请查找 append 方法一次,然后定期追加:
>>> def testc():
... a = []
... pr = cProfile.Profile()
... pr.enable()
... list_append = a.append
... for i in range(100000):
... list_append(1)
... pr.disable()
... pr.print_stats()
您使用的探查器有误。它不会报告从打开到关闭之间经过的时间;它正在收集有关在您打开它和关闭它之间调用的函数的统计信息。 testb
中的大循环没有计时,因为没有函数调用发生。
如果您只是想计时,cProfile
不是合适的工具。我通常会推荐 timeit
,但由于 testb
太长了,所以 time.time()
也合适:
def testb():
start = time.time()
a = []
for i in range(100000):
a = a + [1]
print time.time() - start
玩一下python分析器,看下面的代码:
>>> def testa():
... a = []
... pr = cProfile.Profile()
... pr.enable()
... for i in range(100000):
... a.append(1)
... pr.disable()
... pr.print_stats()
>>> def testb():
... a = []
... pr = cProfile.Profile()
... pr.enable()
... for i in range(100000):
... a = a + [1]
... pr.disable()
... pr.print_stats()
基本上我想看看 append
方法与自连接列表之间的结果,我认为自连接会更昂贵,当我调用 testb
实际用了更长时间才完成。
但是探查器的结果是错误的?
>>> testa()
100002 function calls in 0.006 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
100000 0.005 0.000 0.005 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.001 0.001 0.001 0.001 {range}
>>> testb()
2 function calls in 0.001 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.001 0.001 0.001 0.001 {range}
Python 必须每次查找列表的 "append" 方法的含义。语言是非常动态的,方法可以随时改变。要改进这一点,请查找 append 方法一次,然后定期追加:
>>> def testc():
... a = []
... pr = cProfile.Profile()
... pr.enable()
... list_append = a.append
... for i in range(100000):
... list_append(1)
... pr.disable()
... pr.print_stats()
您使用的探查器有误。它不会报告从打开到关闭之间经过的时间;它正在收集有关在您打开它和关闭它之间调用的函数的统计信息。 testb
中的大循环没有计时,因为没有函数调用发生。
如果您只是想计时,cProfile
不是合适的工具。我通常会推荐 timeit
,但由于 testb
太长了,所以 time.time()
也合适:
def testb():
start = time.time()
a = []
for i in range(100000):
a = a + [1]
print time.time() - start