2010-03-08 14 views
7

Estoy pasando por un link about generators que alguien publicó. Al principio él compara las dos funciones a continuación. En su configuración, mostró un aumento de velocidad del 5% con el generador.Velocidad del generador en python 3

Estoy ejecutando Windows XP, Python 3.1.1, y parece que no puedo duplicar los resultados. Sigo mostrando el "modo antiguo" (logs1) como algo más rápido cuando se prueba con los registros proporcionados y hasta 1 GB de datos duplicados.

¿Alguien me puede ayudar a entender qué está pasando de manera diferente?

Gracias!

def logs1(): 
    wwwlog = open("big-access-log") 
    total = 0 
    for line in wwwlog: 
     bytestr = line.rsplit(None,1)[1] 
     if bytestr != '-': 
      total += int(bytestr) 
    return total 

def logs2(): 
    wwwlog = open("big-access-log") 
    bytecolumn = (line.rsplit(None,1)[1] for line in wwwlog) 
    getbytes  = (int(x) for x in bytecolumn if x != '-') 
    return sum(getbytes) 

* edición, el espaciamiento en mal estado en copiar/pegar

+0

Me parece que esas dos funciones son esencialmente las mismas. En ninguno de los casos está construyendo una gran lista, cuando podría haber usado un generador en su lugar. Así que no estoy sorprendido de que corran aproximadamente a la misma velocidad. – MatrixFrog

+0

Eso tiene sentido, solo tengo curiosidad de por qué estaba obteniendo un aumento del 5% en la velocidad y estoy viendo una disminución del 1% consistentemente. – Will

Respuesta

8

Por lo que vale la pena, el objetivo principal de la comparación de velocidad en la presentación fue señalar que el uso de generadores no presenta una gran sobrecarga de rendimiento. Muchos programadores, al ver generadores por primera vez, pueden comenzar a preguntarse sobre los costos ocultos. Por ejemplo, ¿hay todo tipo de magia elegante detrás de escena? ¿El uso de esta función hará que mi programa se ejecute dos veces más despacio?

En general, ese no es el caso. El ejemplo pretende mostrar que una solución de generador puede ejecutarse esencialmente a la misma velocidad, si no algo más rápido en algunos casos (aunque depende de la situación, la versión de Python, etc.). Sin embargo, si observa grandes diferencias de rendimiento entre las dos versiones, sería algo que vale la pena investigar.

+0

¡Gracias por la respuesta! – Will

0

Usted no tiene una respuesta después de casi una media hora. Estoy publicando algo que tiene sentido para mí, no necesariamente la respuesta correcta. Me imagino que esto es mejor que nada después de casi media hora:

El primer algoritmo utiliza un generador. Un generador funciona cargando el primer page de los resultados de la lista (en la memoria) y carga continuamente las páginas sucesivas (en la memoria) hasta que no quede nada por leer de la entrada.

El segundo algoritmo usa dos generadores, cada uno con una declaración if para un total de dos comparaciones por ciclo en comparación con la primera comparación del primer algoritmo.

También el segundo algoritmo llama a la función sum al final en comparación con el primer algoritmo que simplemente sigue agregando enteros relevantes a medida que los encuentra.

Como tal, para entradas lo suficientemente grandes, el segundo algoritmo tiene más comparaciones y una llamada de función adicional que la primera. Esto podría explicar por qué tarda más en terminar que el primer algoritmo.

Esperanza esto ayuda

+0

"Además, el segundo algoritmo llama a la función de suma al final en comparación con el primer algoritmo que simplemente sigue agregando números enteros relevantes a medida que los encuentra". I * think * eso no haría ninguna diferencia porque sum() probablemente no ponga todos los valores en la memoria y luego los agregue. Es probable que los agregue a medida que se repite, al igual que el otro código. – MatrixFrog

1

En las diapositivas de David Beazley que se ha vinculado a, afirma que todas las pruebas se realizaron con "Python 2.5.1 en OS X 10.4.11," y usted dice que está corriendo con pruebas Python 3.1 en Windows XP. Entonces, date cuenta de que estás haciendo una comparación de manzanas a naranjas. Sospecho que de las dos variables, la versión de Python importa mucho más.

Python 3 es una bestia diferente que Python 2. Muchas cosas han cambiado bajo el capó, (incluso dentro de la rama de Python 2). Esto incluye optimizaciones de rendimiento, así como regresiones de rendimiento (consulte, por ejemplo, Beazley's own recent blog post on I/O in Python 3). Por esta razón, los Python Performance Tips estados de páginas de forma explícita,

siempre debe probar estos consejos con su aplicación y la versión de Python tiene la intención de utilizar y no sólo ciegamente acepta que un método es más rápido que el otro .

debo mencionar que un área que puede contar con generadores que ayudan en la reducción es memoria consumo, en lugar de consumo de CPU. Si tiene una gran cantidad de datos donde calcula o extrae algo de cada pieza individual, y no necesita los datos después, los generadores brillarán. Ver generator comprehension para más detalles.

+0

Entendido, sospechaba mucho y por eso publiqué que estaba usando python3. Nuevamente, tenía curiosidad por saber qué estaba pasando de manera diferente. – Will

+0

Buen enlace, gracias. – Will

+0

Si realmente tiene curiosidad, intente ejecutar las pruebas de tiempo con una instalación de Python 2.6; Si eso no le da una diferencia, intente con una instalación de Python 2.5 y vea si todavía no puede replicar los resultados de Beazley. O puede ser flojo como yo y simplemente enviar un correo electrónico a Python-dev. – gotgenes