Linux中的timeit模块与时间模块对时间 - 为什么结果差别很大?

时间:2014-02-15 05:01:18

标签: python performance timeit

大家好!我试图用对象测试字典的创建性能,但我得到了一些奇怪的结果。我使用三种不同的方法来测量在Python中创建大量字典的时间。 第一个解决方案是时间模块。我知道这不准确。测试文件是" node_time.py"

from __future__ import print_function
from time import time

class node(object):
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.right = None
        self.left = None
        self.parent = None
        self.depth = 0
        return

begin = time()
content = [node(i,i) for i in range(1000000)]
print(time()-begin)

第二种方法是timeit模块。这应该是一个更好的选择。测试文件是" node_timeit.py"

from __future__ import print_function
from timeit import repeat

class node(object):
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.right = None
        self.left = None
        self.parent = None
        self.depth = 0
        return

cmd = "content = [node(i,i) for i in range(1000000)]"
prepare = "from __main__ import node"
cost = min(repeat(cmd, prepare, repeat=1, number =1))
print(cost)

第三种方法是使用系统命令" time"在Linux中。测试文件是" node_sys.py"

from __future__ import print_function

class node(object):
    def __init__(self, key, value):
        self.key = key
        self.value = value
        self.right = None
        self.left = None
        self.parent = None
        self.depth = 0
        return

content = [node(i,i) for i in range(1000000)]

最后结果完全不同。

-bash-4.2$ python2 node_time.py
5.93654894829
-bash-4.2$ python2 node_timeit.py
2.6723048687
-bash-4.2$ time python2 node_sys.py
real    0m8.587s
user    0m7.344s
sys     0m0.716s

时间模块方法(测量挂钟时间)的结果应大于当前值。但是使用Linux命令" time",用户CPU时间和sys CPU时间之和将高达8.060秒。哪个结果是正确的?为什么他们如此不同?谢谢你的评论!

1 个答案:

答案 0 :(得分:4)

timetimeit时间之间的差异是因为

  

By default, timeit() temporarily turns off garbage collection during the timing.

当您分配大量内存时,通常循环垃圾收集器会启动以查看它是否可以回收其中一些内存。为了获得更一致的时序,timeit会在计时期间禁用此行为。

将时间与time进行比较,有无垃圾收集:

>>> def t1():
...   s = time.time()
...   content = [node(i, i) for i in range(1000000)]
...   print time.time() - s
...
>>> t1()
3.27300000191
>>> gc.disable()
>>> t1()
1.92200016975

timeit的时间,有无垃圾收集:

>>> gc.enable()
>>> timeit.timeit('content = [node(i, i) for i in range(1000000)]', 'from __main
__ import node; import gc; gc.enable()', number=1)
3.2806941528164373
>>> timeit.timeit('content = [node(i, i) for i in range(1000000)]', 'from __main
__ import node', number=1)
1.8655694847876134

如您所见,两种方法使用相同的GC设置生成相同的时间。

对于命令行time命令,它包括程序的整个运行时,包括解释器设置和拆卸以及其他时序不包括的其他部分。我怀疑差异的一个重要贡献者是释放你分配的所有node个对象所花费的时间:

>>> def t2():
...   s = time.time()
...   [node(i, i) for i in range(1000000)]
...   # List and contents are deallocated
...   print time.time() - s
...
>>> t2()
3.96099996567