Ver mi respuesta about spatial and temporal locality.
En particular, las matrices son bloques de memoria contiguos, por lo que grandes trozos de ellos se cargarán en la memoria caché al primer acceso. Esto hace que sea relativamente rápido acceder a los elementos futuros de la matriz. Por otro lado, las listas vinculadas no se encuentran necesariamente en bloques contiguos de memoria, y podrían generar más errores de caché, lo que aumenta el tiempo que lleva acceder a ellos.
Considere los siguientes diseños de memoria posibles para una serie data
y lista enlazada l_data
de grandes estructuras
Address Contents | Address Contents
ffff 0000 data[0] | ffff 1000 l_data
ffff 0040 data[1] | ....
ffff 0080 data[2] | ffff 3460 l_data->next
ffff 00c0 data[3] | ....
ffff 0100 data[4] | ffff 8dc0 l_data->next->next
| ffff 8e00 l_data->next->next->next
| ....
| ffff 8f00 l_data->next->next->next->next
Si quisiéramos colocar a través de esta matriz, el primer acceso a ffff 0000
esa manera, requerirían para ir a la memoria de recuperar (una operación muy lenta en ciclos de CPU). Sin embargo, después del primer acceso, el resto de la matriz estaría en la memoria caché, y los accesos posteriores serían mucho más rápidos. Con la lista enlazada, el primer acceso al ffff 1000
también requeriría que vayamos a la memoria. Desafortunadamente, el procesador guardará en caché la memoria que rodea esta ubicación, por ejemplo, hasta ffff 2000
. Como puede ver, esto no captura realmente ninguno de los otros elementos de la lista, lo que significa que cuando accedamos al l_data->next
, nuevamente tendremos que ir a la memoria.
Si comprende cómo funciona [cache] (http://en.wikipedia.org/wiki/Locality_of_reference), también comprenderá 1) "Localidad de referencia" es una buena cosa, y 2) acceder a los datos de las matrices suele ser más probable que tenga una buena "localidad" que acceder a los mismos datos de una lista. – paulsm4
Una cosa que vale la pena señalar es que, si bien esto es cierto, una lista vinculada individualmente combinada con un asignador contiguo puede ser un activo enorme, principalmente porque la transferencia de elementos de un contenedor a otro solo implica la lógica del puntero. Sin embargo, si nos fijamos en el diseño de la memoria de estos, es contigua y se ve como una matriz con solo enlaces al siguiente elemento de la matriz, por lo que sigue siendo compatible con la memoria caché (al menos hasta que la lista se reorganice por completo). –