2012-01-28 10 views
7

¿El uso de funciones de orden superior & Lambdas hace que el tiempo de ejecución & sea mejor o peor? Por ejemplo, para multiplicar todos los números en una lista:Funciones de orden superior vs bucles: tiempo de ejecución y eficiencia de memoria?

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

vs

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

¿La versión HOF tiene ninguna ventaja sobre la versión de bucle aparte de que es menos líneas de código/utiliza un enfoque funcional ?

EDIT:

no soy capaz de añadir esto como una respuesta, ya que no tienen la reputación necesaria. Até para perfilar el enfoque HOF bucle & usando timeit según lo sugerido por @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) 

y este es mi resultado:

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 

En un enfoque media del bucle parece ser más rápido que usar Höfs.

+2

¿Está familiarizado con el módulo timeit?Puede probar el rendimiento usted mismo. – DSM

+0

No, no estoy familiarizado. Voy a google para timeit. Supongo que es una herramienta de creación de perfiles. Pero aún me gustaría saber la ventaja de los HOF desde una perspectiva teórica. – Bharat

+0

@RBK El problema es que la perspectiva teórica no responderá a su pregunta (tiempo de ejecución y eficiencia de la memoria). – Icarus

Respuesta

0

Desde mi experiencia los bucles pueden hacer cosas muy rápido, siempre que no estén anidados demasiado profundamente, y con operaciones matemáticas complejas superiores, para operaciones simples y una sola capa de bucles puede ser tan rápido como de cualquier otra manera, tal vez más rápido , siempre que solo se utilicen enteros como índice del bucle o bucles, también dependería de lo que esté haciendo

También podría ser que la función de orden superior produzca tantos bucles como la versión del programa de bucle e incluso podría ser un poco más lenta, tendrías que cronometrarlos a ambos ... solo para estar seguros.

7

Las funciones de orden superior pueden ser muy rápidas.

Por ejemplo, map(ord, somebigstring) es mucho más rápido que la lista por comprensión equivalente [ord(c) for c in somebigstring]. Los antiguos triunfos por tres razones:

  • mapa() antes de tamaños de la cadena de resultado a la longitud de somebigstring. Por el contrario, la lista de comprensión debe realizar muchas llamadas a realloc() a medida que crece.

  • map() solo tiene que hacer una búsqueda para ord, primero comprobando los valores globales, luego verificando y encontrándolos en builtins. La lista de comprensión tiene que repetir este trabajo en cada iteración.

  • El lazo interno para el mapa se ejecuta a velocidad C. El cuerpo del ciclo para la comprensión de la lista es una serie de pasos puros de Python que cada uno necesita ser despachado o manejado por eval-loop.

Estos son algunos horarios para confirmar la predicción:

>>> 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, veo que el mapa() hace muchas cosas de manera más eficiente que otras formas. Supongo que la velocidad dependerá de lo que estamos tratando de lograr. Las discusiones para [Hacer una lista plana fuera de la lista de listas en Python] (http://stackoverflow.com/q/952914/78845) parecen sugerir que los HOF no son los más rápidos. – Bharat

+0

El uso de HOF es accesorio a esa discusión. Los tiempos allí están dominados por otros factores, como la sobrecarga de llamada de función. –

+0

Sí, el mapa parece ser más rápido. Probé tu código de perfil y obtuve los mismos resultados. Voy a hacer un poco más de perfil para convencerme a mí mismo :) – Bharat

Cuestiones relacionadas