2012-01-28 2 views
7

L'utilizzo delle funzioni di ordine superiore & Lambda rende migliore o peggiore l'efficienza di memoria &? Ad esempio, per moltiplicare tutti i numeri in un elenco:Ordine superiore Funzioni vs cicli - tempo di esecuzione ed efficienza della memoria?

nums = [1,2,3,4,5] 
prod = 1 
for n in nums: 
    prod*=n 

vs

prod2 = reduce(lambda x,y:x*y , nums) 

ha la versione HOF ha alcun vantaggio rispetto alla versione circuito diverso da quello che è linee minori di codice/utilizza un approccio funzionale ?

EDIT:

io non sono in grado di aggiungere questo come una risposta come io non ho la reputazione necessaria. Ho legato al profilo l'approccio del ciclo & HOF utilizzando timeit come suggerito da @DSM

def test1():   
    s= """ 
    nums = [a for a in range(1,1001)] 
    prod = 1 
    for n in nums: 
     prod*=n 
    """    
    t = timeit.Timer(stmt=s) 
    return t.repeat(repeat=10,number=100)  

def test2(): 
    s=""" 
    nums = [a for a in range(1,1001)]  
    prod2 = reduce(lambda x,y:x*y , nums) 
    """ 
    t = timeit.Timer(stmt=s) 
    return t.repeat(repeat=10,number=100) 

E questo è il mio risultato:

Loop: 
[0.08340786340144211, 0.07211491653462579, 0.07162720686361926, 0.06593182661083438, 0.06399049758613146, 0.06605228229559557, 0.06419744588664211, 0.0671893658461038, 0.06477527090075941, 0.06418023793167627] 
test1 average: 0.0644778902685 
HOF: 
[0.0759414223099324, 0.07616920129277016, 0.07570730355421262, 0.07604965128984942, 0.07547092059389193, 0.07544737286604364, 0.075532959799953, 0.0755039779810629, 0.07567424616704144, 0.07542563650187661] 
test2 average: 0.0754917512762 

Su un approccio media ciclo sembra essere più veloce rispetto all'utilizzo Hofs.

+2

Sei familiarità con il modulo timeit?Puoi testare la performance da solo. – DSM

+0

No, non lo conosco. Io google per timeit. Immagino che uno strumento di profilazione. Ma comunque mi piacerebbe conoscere il vantaggio di HOF da una prospettiva teorica. – Bharat

+0

@ RBK Il problema è che la prospettiva teorica non risponderà alla tua domanda (tempo di esecuzione ed efficienza della memoria). – Icarus

risposta

0

dalla mia esperienza, i loop possono fare le cose molto velocemente, purché non siano nidificati troppo profondamente e con complesse operazioni matematiche più elevate, per operazioni semplici e un singolo strato di loop può essere veloce come in qualsiasi altro modo, forse più veloce , purché vengano utilizzati solo numeri interi come indice del ciclo o dei loop, in realtà dipende da ciò che si sta facendo anche

Inoltre, è possibile che la funzione di ordine superiore produca altrettanti cicli come la versione del programma di loop e potrebbe anche essere un po 'più lenta, bisognerebbe crearli entrambi ... solo per essere sicuri.

7

Le funzioni di ordine superiore possono essere molto veloci.

Per esempio, map(ord, somebigstring) è molto più veloce rispetto alla lista di comprensione equivalente [ord(c) for c in somebigstring]. Il primo vince per tre motivi:

  • mappa() pre-dimensioni della stringa risultato alla lunghezza del somebigstring. Al contrario, la list-comprehension deve effettuare molte chiamate a realloc() man mano che cresce.

  • mappa() ha solo a che fare una ricerca per ord, prima controllando globali, quindi il controllo e trovando in comandi incorporati. La comprensione delle liste deve ripetere questo lavoro ad ogni iterazione.

  • Il ciclo interno per la mappa viene eseguito alla velocità C. Il corpo del ciclo per la comprensione delle liste è una serie di passi Python puri che devono essere inviati o gestiti dal ciclo eval.

Ecco alcuni tempi per confermare la previsione:

>>> from timeit import Timer 
>>> print min(Timer('map(ord, s)', 's="x"*10000').repeat(7, 1000)) 
0.808364152908 
>>> print min(Timer('[ord(c) for c in s]', 's="x"*10000').repeat(7, 1000)) 
1.2946639061 
+0

Oh, vedo che map() fa molte cose in modo più efficiente rispetto ad altri modi. Immagino che la velocità dipenda da ciò che stiamo cercando di ottenere. Le discussioni per [Creare un elenco semplice dall'elenco di elenchi in Python] (http://stackoverflow.com/q/952914/78845) sembra suggerire che le HOF non sono le più veloci. – Bharat

+0

L'uso di HOF è secondario a quella discussione. I tempi ci sono dominati da altri fattori come la funzione chiamata overhead. –

+0

Sì, la mappa sembra essere più veloce. Ho provato il tuo codice di profilazione e ho ottenuto gli stessi risultati. Ho intenzione di fare un po 'più di profilazione per convincermi :) – Bharat