Siehe meine Antwort about spatial and temporal locality.
Insbesondere Arrays sind zusammenhängende Speicherblöcke, so dass große Teile davon beim ersten Zugriff in den Cache geladen werden. Dies ermöglicht einen vergleichsweise schnellen Zugriff auf zukünftige Elemente des Arrays. Verknüpfte Listen andererseits befinden sich nicht notwendigerweise in zusammenhängenden Speicherblöcken und könnten zu mehr Cache-Misses führen, was die Zeit erhöht, die für den Zugriff auf sie benötigt wird.
Betrachten Sie das folgende mögliche Speicherlayout für ein Array data
und verkettete Liste l_data
großen structs
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 eine Schleife durch dieses Array, der erste Zugriff auf ffff 0000
erfordern würde uns in den Speichern zu gehen, wollten abrufen (ein sehr langsamer Vorgang in CPU-Zyklen). Nach dem ersten Zugriff wäre der Rest des Arrays jedoch im Cache, und nachfolgende Zugriffe wären viel schneller. Mit der verknüpften Liste würde der erste Zugriff auf ffff 1000
auch erfordern, dass wir in den Speicher gehen. Unglücklicherweise speichert der Prozessor den Speicher, der diesen Ort direkt umgibt, bis zu ffff 2000
. Wie Sie sehen können, erfasst dies tatsächlich keine der anderen Elemente der Liste, was bedeutet, dass wir, wenn wir auf zugreifen, erneut in den Speicher gehen müssen.
Wenn Sie verstehen, wie [Cache] (http://en.wikipedia.org/wiki/Locality_of_reference) funktioniert, dann werden Sie auch verstehen 1) "Ort der Referenz" ist eine gute Sache, und 2) Zugriff auf Daten von Arrays ist in der Regel eher eine gute "Lokalität" als der Zugriff auf dieselben Daten aus einer Liste. – paulsm4
Bemerkenswert ist, dass, obwohl dies zutrifft, eine einfach verknüpfte Liste in Kombination mit einem zusammenhängenden Zuordner ein enormer Vorteil sein kann, vor allem weil die Übertragung von Elementen von einem Container zu einem anderen nur die Zeigerlogik betrifft. Wenn Sie sich das Speicherlayout ansehen, ist es jedoch zusammenhängend und sieht aus wie ein Array mit nur Verknüpfungen zum nächsten Element im Array, und daher ist es immer noch Cache-freundlich (zumindest bis die Liste vollständig reorganisiert ist). –