为什么python profiler会产生矛盾的结果呢?

时间:2015-07-19 22:44:03

标签: python profiling profiler

在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}

2 个答案:

答案 0 :(得分:0)

Python必须查找"追加"列表的方法意味着每次。语言非常动态,方法可能随时都有变化。要改进这一点,请查看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()

答案 1 :(得分:0)

您使用的是错误的分析器。它没有报告开启和关闭之间经过的时间;它正在收集关于打开它和关闭它之间调用的函数的统计信息。 testb中昂贵的大循环没有定时,因为没有函数调用。

如果您只是想要时间,cProfile不是要使用的工具。我通常会建议使用timeit,但由于testb需要如此荒谬,time.time()也是合适的:

def testb():
    start = time.time()
    a = []
    for i in range(100000):
        a = a + [1]
    print time.time() - start