Incohérence entre %time et %timeit dans IPython

Je suis confronté à une situation bizarre que je ne peux pas expliquer. Voici mon test de synchronisation de la génération d'une grande liste de tuples:

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

Comme vous pouvez le voir, la génération de cette grande liste de tuples prend juste en dessous d'un deuxième. timeit indique que le temps d'exécution est d'environ 0,1 seconde. Pourquoi est-il une si grande différence dans les deux rapports?

(testé sur IPython 0.11, Python 2.6.5.)

23
demandé sur badzil 2011-12-23 21:55:07

3 réponses

La principale différence est que "par défaut, timeit () désactive temporairement la collecte des ordures pendant le temps".

Transformer la récupération de place renvoie des résultats similaires à ceux indiqués dans la question, c'est-à-dire que le moment de l'exécution avec la récupération de place est plus grand que celui sans:

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.
29
répondu badzil 2012-01-04 17:59:27

Benoit,

Si J'utilise python 2.6.6 et IPython 0.10 alors je vois des réponses similaires à la vôtre. En utilisant python 2.7.1 et IPython 0.10.1, j'obtiens quelque chose de plus sensible:

% 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
3
répondu Doug Burke 2011-12-23 19:02:09

%time - runs instruction une seule fois, et ont erreur de mesure

% timeit-exécute l'instruction quelques fois, et choisit l'heure la plus précise.

Voir documentation du module Python timeit pour quelques explications

-5
répondu reclosedev 2011-12-23 19:17:14