2011-12-23 12 views
22

Me enfrento a una situación extraña que no puedo explicar. Aquí está mi prueba de tiempo la generación de una gran lista de tuplas:Inconsistencia entre% time y% timeit en IPython

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 

Como se puede ver, la generación de esta larga lista de tuplas toma justo debajo de un segundo. timeit informa que el tiempo de ejecución es de alrededor de 0.1 segundo. ¿Por qué hay una gran diferencia en los dos informes?

(Probado en IPython 0,11, Python 2.6.5.)

+1

se obtiene el mismo resultado si se ejecuta % timeit primero y% time second? – sth

+1

Interesante comentario. Sí, obtengo resultados similares con un orden de ejecución invertido. – badzil

+0

No conozco IronPython, así que no puedo decir mucho sobre '% time' o'% timeit', pero supongo que '% time' repite la prueba de tiempo 10 veces. –

Respuesta

29

La principal diferencia se debe a que "by default, timeit() temporarily turns off garbage collection during the timing".

Pasando los rendimientos de recolección de basura resultados similares a la mostrada en la cuestión, es decir, el momento de la ejecución con la recolección de basura es de magnitud más grande que el que no tiene:

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. 
3

Benoit,

Si uso de Python 2.6.6 y 0.10 IPython luego veo respuestas similares a la suya. Al utilizar Python 2.7.1 y 0.10.1 IPython que conseguir algo más sensato: tiempo

% 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 
+0

Obtuve resultados muy similares con IPython 0.11 y Python 2.7.2. – badzil

-6

% - instrucción se ejecuta sólo una vez, y tienen un error de medición

% timeit - ejecuta la instrucción pocas veces, y más choses tiempo exacto.

Ver Python timeit module documentation para algunas explicaciones

+4

"RTFM" no es una respuesta a mi pregunta. Si genero una lista de 10 millones de tuplas en lugar de 1 millón, el% de tiempo informa 56 s y el% de tiempo informa 882 ms. Esto no es normal y quiero saber por qué. – badzil

+0

@ badzil, ¿ha intentado ejecutar% veces varias veces a mano? ¿Los resultados son los mismos? Y si tiene 2.6 y 2.7 intente desmontar y encontrar diferencias entre los códigos generados (tengo solo 2.7) – reclosedev

+0

Los resultados son consistentes si ejecuto% time y% timeit varias veces. ¿Puedes elaborar sobre el código generado? – badzil