Python3 vs Python2 rendimiento de rango de lista / generador

Tengo esta función simple que particiona una lista y devuelve un índice i en la lista, de modo que los elementos en los índices menos que yo sean más pequeños que la lista [i] y los elementos en los índices mayores que i sean más grandes.

def partition(arr): first_high = 0 pivot = len(arr) - 1 for i in range(len(arr)): if arr[i] < arr[pivot]: arr[first_high], arr[i] = arr[i], arr[first_high] first_high = first_high + 1 arr[first_high], arr[pivot] = arr[pivot], arr[first_high] return first_high if __name__ == "__main__": arr = [1, 5, 4, 6, 0, 3] pivot = partition(arr) print(pivot) 

El tiempo de ejecución es sustancialmente mayor con python 3.4 que python 2.7.6 en OS X:

 time python3 partition.py real 0m0.040s user 0m0.027s sys 0m0.010s time python partition.py real 0m0.031s user 0m0.018s sys 0m0.011s 

Lo mismo en ubuntu 14.04 / caja virtual

python3:

 real 0m0.049s user 0m0.034s sys 0m0.015s 

python:

 real 0m0.044s user 0m0.022s sys 0m0.018s 

Python3 es intrínsecamente más lento que python2.7 o hay alguna optimización específica para que el código se ejecute tan rápido como en python2.7

Como se mencionó en los comentarios, debe realizar una evaluación comparativa con timeit lugar de con las herramientas del sistema operativo.

Supongo que la función de range probablemente se está realizando un poco más lento en Python 3. En Python 2 simplemente devuelve una lista , en Python 3 devuelve un range que se comporta más o menos como un generador. Hice algunas evaluaciones comparativas y este fue el resultado, lo que puede ser un indicio de lo que estás experimentando:

 python -mtimeit "range(10)" 1000000 loops, best of 3: 0.474 usec per loop python3 -mtimeit "range(10)" 1000000 loops, best of 3: 0.59 usec per loop python -mtimeit "range(100)" 1000000 loops, best of 3: 1.1 usec per loop python3 -mtimeit "range(100)" 1000000 loops, best of 3: 0.578 usec per loop python -mtimeit "range(1000)" 100000 loops, best of 3: 11.6 usec per loop python3 -mtimeit "range(1000)" 1000000 loops, best of 3: 0.66 usec per loop 

Como puede ver, cuando la entrada proporcionada al range es pequeña , tiende a ser rápida en Python 2. Si la entrada aumenta, entonces el range Python 3 range comporta mejor.

Mi sugerencia: pruebe el código para matrices más grandes, con cien o mil elementos.

En realidad, fui más allá y probé una iteración completa a través de los elementos. Los resultados fueron totalmente a favor de Python 2:

 python -mtimeit "for i in range(1000):pass" 10000 loops, best of 3: 31 usec per loop python3 -mtimeit "for i in range(1000):pass" 10000 loops, best of 3: 45.3 usec per loop python -mtimeit "for i in range(10000):pass" 1000 loops, best of 3: 330 usec per loop python3 -mtimeit "for i in range(10000):pass" 1000 loops, best of 3: 480 usec per loop 

Mi conclusión es que probablemente es más rápido iterar a través de una lista que a través de un generador. Aunque este último es definitivamente más eficiente en cuanto al consumo de memoria. Este es un ejemplo clásico del intercambio entre velocidad y memoria. Aunque la diferencia de velocidad no es tan grande en sí misma (menos de milisegundos). Así que debes valorar esto y lo que es mejor para tu progtwig.