27

我遇到了一个我无法解释的奇怪情况。这是我生成大量元组的测试时间:

In [1]: def get_list_of_tuples():
   ...:     return [(i,) for i in range(10**6)]
   ...:

In [2]: %time res = get_list_of_tuples()
CPU times: user 0.93 s, sys: 0.08 s, total: 1.01 s
Wall time: 0.98 s

In [3]: %timeit res = get_list_of_tuples()
1 loops, best of 3: 92.1 ms per loop

如您所见,生成这个庞大的元组列表只需要不到一秒钟的时间。timeit 报告执行时间约为 0.1 秒。为什么两份报告的差异如此之大?

(在 IPython 0.11、Python 2.6.5 上测试。)

4

3 回答 3

41

主要区别在于“默认情况下,timeit() 在计时期间会暂时关闭垃圾收集”。

转动垃圾收集返回的结果类似于问题中显示的结果,即垃圾收集的执行时间比没有垃圾收集的执行时间大:

In [1]: import timeit

# Garbage collection on.
In [2]: N = 10; timeit.timeit('[(i,) for i in range(10**6)]', 'gc.enable()', number=N) / N
Out[2]: 0.74884700775146484
# 749 ms per loop.

# Garbage collection off.
In [3]: N = 10; timeit.timeit('[(i,) for i in range(10**6)]', number=N) / N
Out[3]: 0.15906109809875488
# 159 ms per loop.
于 2012-01-04T17:59:27.570 回答
3

贝努瓦,

如果我使用 Python 2.6.6 和 IPython 0.10,那么我会看到与您类似的答案。使用 Python 2.7.1 和 IPython 0.10.1 我得到了一些更明智的东西:

% ipython
Python 2.7.1 (r271:86832, Nov  3 2011, 16:23:57) 
Type "copyright", "credits" or "license" for more information.

IPython 0.10.1 -- An enhanced Interactive Python.

In [1]: def get_list_of_tuples():
   ...:     return [(i,) for i in range(10**6)]
   ...: 

In [2]: %time res = get_list_of_tuples()
CPU times: user 0.25 s, sys: 0.10 s, total: 0.35 s
Wall time: 0.35 s

In [3]: %timeit res = get_list_of_tuples()
1 loops, best of 3: 215 ms per loop
于 2011-12-23T19:02:09.293 回答
-5

%time - 只运行一次语句,并且有测量错误

%timeit - 运行语句几次,并选择最准确的时间。

有关一些解释,请参阅Python timeit 模块文档

于 2011-12-23T19:17:14.210 回答