IPython中%time与%timeit不一致

28 投票
3 回答
17630 浏览
提问于 2025-04-17 08:55

我遇到了一个奇怪的情况,无法解释。下面是我测试生成一个大元组列表的时间:

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上测试。)

3 个回答

-5

%time 是用来运行一个语句一次的,它会有一些测量误差。

%timeit 则是运行一个语句多次,然后选择最准确的时间。

想了解更多,可以查看 Python 的 timeit 模块文档,里面有一些解释。

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
43

主要的区别在于“默认情况下,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.

撰写回答