2010-07-17 9 views
9

Estoy aprendiendo Python recientemente, y estoy haciendo muchas prácticas con el idioma.En python, ¿por qué la lectura de una matriz es más lenta que la lectura de la lista?

Una cosa que me pareció interesante es que, cuando leo de una matriz, es casi la mitad de las veces más lenta que la lista. ¿Alguien sabe por qué?

aquí es mi código:

 
from timeit import Timer 
import array 

t = 10000 
l = range(t) 
a = array.array('i', l) 
def LIST(): 
    for i in xrange(t): 
     l[i] 

def ARRAY(): 
    for i in xrange(t): 
     a[i] 

print Timer(LIST).timeit(1000); 
print Timer(ARRAY).timeit(1000); 

la salida es:

 
0.813191890717 
1.16269612312 

matriz que indica que la lectura es más lenta que la lista. Creo que la matriz es una memoria de tamaño fijo, mientras que la lista es una estructura dinámica. Así que asumí que la matriz sería más rápida que la lista.

¿Alguien tiene alguna explicación?

+1

posible dupe/answer: http://stackoverflow.com/questions/176011/python-list-vs-array-when-to-use - Básicamente array.array es un contenedor alrededor de una matriz C así que creo que hay sobrecarga al acceder a ella. No lo use para matemáticas. –

+0

Intentar adivinar las eficiencias de Python, especialmente para aquellas que provienen de un fondo tipo C, a menudo no es intuitivo. Código claramente primero, luego optimice si mide un problema de rendimiento; esto también se aplica a C, pero debido a que los elementos del lenguaje están tan cerca de la máquina, la gente suele olvidar. – msw

+1

Para matemáticas puede usar numpy (aún no disponible para python 3), solo Dios sabe por qué numpy no es una biblioteca estándar. –

Respuesta

8

Lleva tiempo envolver un entero sin formato en Python int.

+2

Bastante bien. La función LIST solo tiene que incrementar y luego disminuir el recuento de referencias para cada elemento de la lista. La función ARRAY por otro lado tiene que asignar memoria para cada uno de los enteros (excepto los más pequeños que tienen una optimización) y luego liberarlo de nuevo. – Duncan

1

Las listas de Python se parecen mucho a las matrices normales, no son listas Lisp, pero tienen acceso aleatorio rápido.

8

list s son "vectores de crecimiento dinámico" (muy parecido a C++ 's std::vector, por ejemplo), pero que de ninguna manera se ralentiza el acceso aleatorio a ellos (que no están vinculados listas -!). Las entradas de las listas son referencias a objetos de Python (los elementos): el acceso a uno solo requiere (en CPython) un incremento del recuento de referencias del artículo (en otras implementaciones, basado en una recolección de basura más avanzada, ni siquiera eso ;-). Las entradas de Array son bits y bytes en bruto: el acceso a uno requiere un nuevo objeto de Python nuevo para sintetizar en función de ese valor binario. Por ejemplo:

$ python -mtimeit -s'import array; c=array.array("B", "bzap")' 'c[2]' 
10000000 loops, best of 3: 0.0903 usec per loop 
$ python -mtimeit -s'c=list("bzap")' 'c[2]' 
10000000 loops, best of 3: 0.0601 usec per loop 

El tiempo extra de 30 nanosegundos para un acceso no parece tan malo ;-).

Como nota aparte, tenga en cuenta que timeit es MUCHO mejor de usar desde la línea de comandos - elección automática de repetición, unidad de medida mostrada por el tiempo, etc. Así es como siempre lo uso (importación de un módulo personalizado) con funciones para llamar, si es necesario, pero aquí no hay necesidad de eso) - es así que ¡mucho más útil que importarlo y usarlo desde un módulo!

Cuestiones relacionadas