2010-04-18 58 views
24

Possibili duplicati:
Accurate timing of functions in python
accurately measure time python function takescome misurare il tempo di esecuzione di algoritmi in python

Come posso mesure e confrontare i tempi di esecuzione dei miei algoritmi scritto in Python .Anche indicami un bel sito/forum di algoritmi come StackOverflow se puoi.

+2

simili http://stackoverflow.com/questions/889900/accurate-timing-of-functions-in-python –

+0

Entrambi questi fili erano circa temporizzazione * * funzioni, che può o non può essere quello è richiesto di fare "algoritmi di temporizzazione", che mi sembra un compito mal definito. Potrebbe richiedere cose molto più complesse del cronometrare una funzione. –

+0

Inoltre, le domande sugli algoritmi (purché siano correlate alla programmazione) sono sicuramente benvenute su Stack Overflow. –

risposta

18

Io non sono sicuro al 100% che cosa si intende per "i tempi dei miei algoritmi scritto in Python in esecuzione", così ho pensato che avrei potuto cercare di offrire uno sguardo più ampio ad alcuni dei potenziali risposte

  • algoritmi non hanno tempi di esecuzione; le implementazioni possono essere cronometrate, ma un algoritmo è un approccio astratto per fare qualcosa. La parte più comune e spesso più utile dell'ottimizzazione di un programma è analyzing the algorithm, in genere utilizzando l'analisi asintotica e calcolando la complessità dello big O in termini di tempo, spazio, utilizzo del disco e così via.

    Un computer non può davvero fare questo passo per voi. Ciò richiede di fare i conti con la matematica per capire come funziona qualcosa. Ottimizzare questo aspetto delle cose è il componente principale per avere prestazioni scalabili.

  • È possibile calcolare l'ora dell'implementazione specifica. Il modo migliore per farlo in Python è usare timeit. Il modo in cui sembra più voler essere utilizzato è di creare un modulo con una funzione che incapsula ciò che si desidera chiamare e chiamarlo dalla riga di comando con python -m timeit ....

    Utilizzare timeit per confrontare più frammenti quando si esegue la microottimizzazione, ma spesso non è lo strumento corretto che si desidera per confrontare due diversi algoritmi. È comune che quello che vuoi sia l'analisi asintotica, ma è possibile che tu voglia tipi di analisi più complicati.

  • È necessario sapere che ora è necessario. La maggior parte dei frammenti non vale la pena di essere migliorata. È necessario apportare modifiche laddove contano effettivamente, in particolare quando si esegue la micro-ottimizzazione e non si migliora la complessità asintotica del proprio algoritmo.

    Se quadruplicate la velocità di una funzione in cui il vostro codice passa l'1% del tempo, non si tratta di una vera accelerazione. Se aumenti la velocità del 20% su una funzione in cui il tuo programma trascorre il 50% delle volte, ottieni un guadagno reale.

    Per determinare il tempo trascorso da un vero programma Python, utilizzare stdlib profiling utilities. Questo ti dirà dove in un programma di esempio il tuo codice sta spendendo il suo tempo.

+3

-1 per dirgli che non capisci la sua domanda per fare un punto esoterico, e poi continuare a rispondere alle sue domande, che hai capito fin dall'inizio. – Greg

23

Il modulo timeit è utile per questo ed è incluso nella distribuzione standard di Python.

Esempio:

import timeit 
timeit.Timer('for i in xrange(10): oct(i)').timeit() 
20

Per le piccole algoritmi è possibile utilizzare il modulo timeit dalla documentazione python:

def test(): 
    "Stupid test function" 
    L = [] 
    for i in range(100): 
     L.append(i) 

if __name__=='__main__': 
    from timeit import Timer 
    t = Timer("test()", "from __main__ import test") 
    print t.timeit() 

Meno precisione, ma ancora valido è possibile utilizzare il tempo del modulo come questo:

from time import time 
t0 = time() 
call_mifuntion_vers_1() 
t1 = time() 
call_mifunction_vers_2() 
t2 = time() 

print 'function vers1 takes %f' %(t1-t0) 
print 'function vers2 takes %f' %(t2-t1) 
+0

+1 per mostrare come eseguire timeit su una funzione in __main__. Utile quando si confrontano diversi metodi di fare qualcosa – Patrick

+1

Anche se un link a dove l'hai ottenuto sarebbe stato ancora più utile ... ;-) https://docs.python.org/2/library/timeit.html#examples – Patrick

0

Il linguaggio di programmazione non ha importanza; misurare la complessità del tempo di esecuzione di un algoritmo funziona allo stesso modo indipendentemente dalla lingua. Analysis of Algorithms di Stanford su Google Code University è una risorsa molto buona per insegnare a te stesso come analizzare la complessità di runtime di algoritmi e codice.

Se tutto ciò che si vuole fare è misurare il tempo trascorso che una funzione o una parte di codice impiega per funzionare in Python, allora si possono usare i moduli timeit o time, a seconda di quanto a lungo deve essere eseguito il codice.

+0

La domanda riguarda il tempo di esecuzione, non il tempo di calcolo effettivo. – SeF

+0

@SeF, potresti averlo interpretato in questo modo, ma non è esplicito nella domanda. E dato che dice "algoritmo" piuttosto che "implementazione", l'interpretazione assunta da questa risposta è entro limiti ragionevoli. –

+0

@SeF, in aggiunta a quanto sopra, data l'ambiguità, la mia risposta affronta entrambe le interpretazioni della domanda (la mia risposta cita anche timeit), e questa risposta precede quelle che approfondiscono l'uso del modulo timeit. –

13

Utilizzare un decoratore per misurare i tempi di esecuzione delle funzioni può essere utile. C'è un esempio su http://www.zopyx.com/blog/a-python-decorator-for-measuring-the-execution-time-of-methods.

Di seguito ho incollato senza vergogna il codice dal sito menzionato in precedenza in modo che l'esempio esista in SO nel caso in cui il sito venga cancellato dalla rete.

import time             

def timeit(method): 

    def timed(*args, **kw): 
     ts = time.time() 
     result = method(*args, **kw) 
     te = time.time() 

     print '%r (%r, %r) %2.2f sec' % \ 
       (method.__name__, args, kw, te-ts) 
     return result 

    return timed 

class Foo(object): 

    @timeit 
    def foo(self, a=2, b=3): 
     time.sleep(0.2) 

@timeit 
def f1(): 
    time.sleep(1) 
    print 'f1' 

@timeit 
def f2(a): 
    time.sleep(2) 
    print 'f2',a 

@timeit 
def f3(a, *args, **kw): 
    time.sleep(0.3) 
    print 'f3', args, kw 

f1() 
f2(42) 
f3(42, 43, foo=2) 
Foo().foo() 

// John

+0

È possibile passare i risultati timeit al processo chiamante; o altrimenti emettere il risultato timeit dopo aver chiamato il metodo? (Il tempo che veniva emesso prima che lo stdout delle chiamate mi buttasse fuori) – ThorSummoner

Problemi correlati