2011-12-23 15 views
22

Mam do czynienia z dziwną sytuacją, której nie potrafię wyjaśnić. Oto moja próba rozrządu generowanie dużej listę krotek:Niespójność między% time i% timeit w 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 

Jak widać, pokolenie to dużą listę krotek trwa zaledwie poniżej sekundy. timeit informuje, że czas wykonania wynosi około 0,1 sekundy. Dlaczego w obu raportach występuje tak duża różnica?

(Testowane na ipython 0,11, Python 2.6.5.)

+1

Czy można uzyskać ten sam rezultat, jeśli uruchomić % timeit pierwszy a% czas drugi? – sth

+1

Interesujący komentarz. Tak, otrzymuję podobne wyniki w odwrotnej kolejności wykonania. – badzil

+0

Nie znam IronPythona, więc nie mogę powiedzieć wiele o '% time' lub'% timeit', ale domyślam się, że '% time' powtórzy test czasowy 10 razy. –

Odpowiedz

29

Główną różnicą jest to, ponieważ "by default, timeit() temporarily turns off garbage collection during the timing".

Włączanie powraca zbiórki śmieci wyniki podobne do przedstawionego w pytaniu, czyli czas realizacji ze zbieraniem śmieci jest wielkość większa niż jeden bez:

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,

Jeśli używam Python 2.6.6 i ipython 0,10 potem widzę podobne odpowiedzi na twoje. Korzystanie Python 2.7.1 i ipython 0.10.1 uzyskać coś bardziej sensownego:

% 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

Mam bardzo podobne wyniki z IPython 0.11 i Python 2.7.2. – badzil

-6

% czasu - uruchamia oświadczenie tylko raz i ma błąd pomiaru

% timeit - uruchamia oświadczenie kilka razy, i wybiera najbardziej dokładny czas.

Zobacz Python timeit module documentation dla niektórych wyjaśnień

+4

"RTFM" nie jest odpowiedzią na moje pytanie. Jeśli wygeneruję listę 10 milionów krotek zamiast 1 miliona,% raportów czasu 56 i% raportów timeit 882 ms. To nie jest normalne i chcę wiedzieć dlaczego. – badzil

+0

@badzil, czy próbowałeś wykonać% razy kilka razy ręcznie? Czy wyniki są takie same? A jeśli masz zarówno 2.6, jak i 2.7 spróbuj rozłożyć i znaleźć różnice między wygenerowanymi kodami (mam tylko 2.7) – reclosedev

+0

Wyniki są spójne, jeśli uruchomię% time and% timeit kilka razy. Czy możesz rozwinąć wygenerowany kod? – badzil

Powiązane problemy