2015-11-26 15 views
6

Il comando magico %timeit è ottimo per misurare i tempi di esecuzione del codice in modo interattivo. Tuttavia, voglio ottenere il risultato di %timeit per tracciare i risultati. timeit.timeit consente anche questo, ma non ha il ridimensionamento automatico del numero di iterazioni e la normalizzazione del risultato che ha %timeit.% timeit equivalente nel codice

Esiste una funzione incorporata in grado di temporizzare un pezzo di codice, che regola anche automaticamente il numero di iterazioni eseguite e restituisce un risultato normalizzato?

+1

Penso che non c'è, ma per la temporizzazione si può basta creare un decoratore di timer, il contatore di iterazioni non è così facile da farlo funzionare come vorresti. – Netwave

+0

https://github.com/ipython/ipython/blob/acb2c91c5522bf1c0cb1c06c1882044a08cdf09b/IPython/core/magics/execution.py#L902 - anche se probabilmente non è utilizzabile dal punto di vista dell'utente. – Caramiriel

risposta

4

Il comando magia %timeit offre un'opzione -o:

-o: restituire un TimeitResult che può essere memorizzato in una variabile per ispezionare il risultato in ulteriori dettagli.

Stampa il risultato ma restituisce anche il risultato in modo che possa essere catturato in una variabile. La sintassi per i comandi di magia è un po 'limitato, ma si poteva raccogliere i diversi risultati in una list assegnandolo ad una variabile e aggiungendo quella variabile a un elenco:

res = [] 
for i in range(3): 
    a = %timeit -o 10*10 
    res.append(a) 
# 10000000 loops, best of 3: 61 ns per loop 
# 10000000 loops, best of 3: 61.1 ns per loop 
# 10000000 loops, best of 3: 60.8 ns per loop 

e quindi accedere res:

print(res) 
# [<TimeitResult : 10000000 loops, best of 3: 61.2 ns per loop>, 
# <TimeitResult : 10000000 loops, best of 3: 61.3 ns per loop>, 
# <TimeitResult : 10000000 loops, best of 3: 61.5 ns per loop>] 

Ognuno di questi risultati ha diversi attributi, che potrebbero essere di interesse:

print(res[0].all_runs) 
# [0.6166532894762563, 0.6102780388983005, 0.6370787790842183] 
print(res[0].best) 
# 6.102780388983005e-08 
print(res[0].compile_time) 
# 0.00020554513866197934 
print(res[0].loops) 
# 10000000 
print(res[0].repeat) 
# 3 
print(res[0].worst) 
# 1.1170931449020795e-06 

per tracciare per esempio i migliori tempi si necessario creare un nuovo elenco contenente i migliori valori:

res_best_times = [result.best * 1e9 for result in res] 
# "* 1e9" to get the result in nanoseconds 
print(res_best_times) 
# [61.2, 61.3, 61.5] 
2

Supponendo che si può usare/importazione IPython, e si vuole semplicemente creare uno script senza testa che utilizza la magia %timeit, si potrebbe fare qualcosa di simile a quanto segue.

Assumere il seguente è nel file testme.py:

from IPython import get_ipython 

def myfun(x): 
    return x**x 

val = 12.3 
out = get_ipython().run_line_magic("timeit","-o myfun({})".format(val)) 

#do something with out, which will be a TimeitResult object 

Quindi è possibile eseguire lo script in modo non interattivo con:

ipython testme.py 
+0

Mi sono basato sul suggerimento di @ MSeifert di usare il flag -o sulla magia per catturare l'output ... – svohara