2015-04-28 12 views
9

Ecco un esempio di quello che voglio dire:Perché `if` è molto più veloce se controllato prima di un'istruzione rispetto a una dichiarazione?

s = """ 
if x > 10: 
    x -= 10 
else: 
    x = 0 
""" 
import timeit 
print(timeit.timeit(s, setup="x=5", number=99999999)) 

Uscite circa 3 secondi sul mio computer, a prescindere dalla configurazione (x=5 vs x=15, nessuna differenza)


Se dovessi usare molto codice più corto, uno che prima diminuisce x -= 10 e quindi controlla se x < 0, otterrò risultati molto peggiori:

s = """ 
x -= 10 
if x < 0: 
    x = 0 
""" 
import timeit 
print(timeit.timeit(s, setup="x=5", number=99999999)) 

Emette circa 6 secondi, sempre indipendentemente dal fatto che il valore iniziale di x sia 5 o 15.


Capisco che sarebbe stato più lento quando x < 10 da quando avevamo prima chiamiamo x -= 10 e quindi impostare x = 0 invece di semplicemente impostando x una volta.

Il fatto è che il 99% delle volte il valore iniziale di x nel mio programma è impostato su un numero molto superiore a 10, quindi ho pensato di utilizzare la versione più breve poiché la maggior parte del tempo dovrei vedere nessuna differenza di prestazioni.

Tuttavia, c'è un'enorme differenza di prestazioni anche quando x > 10, perché questo?

+1

questa temporizzazione si verifica in Python 2.7 pure. – dbliss

risposta

7

Il tuo locale è sbagliato. setup viene eseguito una sola volta per l'intero timeit. Se è assicurarsi che x soggiorni superiori 10 poi i sintomi scompaiono:

differenza
>>> s1 = """ 
... if x > 10: 
...  x -= 10 
... else: 
...  x = 0 
... """ 
>>> s2 = """ 
... x -= 10 
... if x < 0: 
...  x = 0 
... """ 
>>> import timeit 
>>> print(timeit.timeit(s1, setup="x=1000000000", number=99999999)) 
8.934118068675566 
>>> print(timeit.timeit(s2, setup="x=1000000000", number=99999999)) 
8.744505329313448 
+1

Ho usato 'timeit.timeit()' un milione di volte prima e dovrei essere molto consapevole di come funziona il parametro di setup ... Divertente come il nostro cervello può perdere qualcosa di così ovvio se pensa che tutto dovrebbe ** lavoro.Grazie per la risposta, buona cattura :) –

+2

@MarkusMeskanen In realtà sono stato morso da questo anche quando ho commentato la risposta di Will, qualcuno mi ha menzionato (ma quella persona ora ha cancellato il suo commento, quindi non posso dare credito perché non lo faccio ricorda). Questa menzione mi ha portato a questa risposta. – orlp

-2

Aggiornamento: errore; lasciando come una registrazione di ciò che non ha causato il comportamento

sembra almeno un po 'probabile che questo è un artefatto del modo in cui il codice viene eseguito sotto timeit.timeit. Si potrebbe verificare questa temporizzazione da una singola esecuzione di codice come:

x = 5 
for i in xrange(99999999): 
    x -= 10 
    if x < 0: 
    x = 0 

per il secondo caso, e confrontando tale temporizzazione per un simile riscrittura della prima.

+0

Ho frainteso il parametro 'setup', quella parte della risposta è almeno corretta. – orlp

+0

@orlp 'xrange' è un built-in in python 2.X. se 'x = 5' è all'interno del ciclo non importa, poiché questa linea è la stessa per entrambi i metodi. che il comportamento rimane dopo aver usato questa risposta non significa che sia una cattiva risposta; significa semplicemente che la differenza non è un artefatto dell'uso di "timeit". – dbliss

+1

@dbliss Ma questo implica che la risposta è negativa, perché è tutta la risposta che dice, no? Tra l'altro il downvote corrente non è mio - ho rimosso il mio fino a un'ulteriore ispezione. – orlp

Problemi correlati