Siehe meine Antwort zur räumlichen und zeitlichen Lokalität .
Insbesondere sind Arrays zusammenhängende Speicherblöcke, so dass große Teile davon beim ersten Zugriff in den Cache geladen werden. Dies macht es vergleichsweise schnell, auf zukünftige Elemente des Arrays zuzugreifen. Verknüpfte Listen hingegen befinden sich nicht unbedingt in zusammenhängenden Speicherblöcken und können zu mehr Cache-Fehlern führen, was die Zugriffszeit erhöht.
Berücksichtigen Sie die folgenden möglichen Speicherlayouts für ein Array data
und eine verknüpfte Liste l_data
großer Strukturen
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
Wenn wir dieses Array durchlaufen ffff 0000
möchten, müssen wir für den ersten Zugriff auf zum Speichern in den Speicher gehen (ein sehr langsamer Vorgang in CPU-Zyklen). Nach dem ersten Zugriff befindet sich der Rest des Arrays jedoch im Cache, und nachfolgende Zugriffe sind viel schneller. Bei der verknüpften Liste ffff 1000
müssten wir für den ersten Zugriff auf auch in den Speicher gehen. Leider wird der Prozessor den Speicher, der diesen Speicherort direkt umgibt, zwischenspeichern, etwa bis zu ffff 2000
. Wie Sie sehen können, erfasst dies keines der anderen Elemente der Liste, was bedeutet, dass wir beim Zugriff l_data->next
erneut in den Speicher wechseln müssen.