Welche Liste Implementierung wird die schnellste für einen Durchgang Schreib sein, lesen, dann zerstören?

StackOverflow https://stackoverflow.com/questions/135314

  •  02-07-2019
  •  | 
  •  

Frage

Was ist die schnellste Liste Implementierung (in Java) in einem Szenario, in dem die Liste wird dann zu einem Zeitpunkt zu einem späteren Zeitpunkt gelesen werden, um ein Element zu einem Zeitpunkt ein Element geschaffen werden? Das liest, wird mit einem Iterator durchgeführt werden und dann wird die Liste dann zerstört werden.
Ich weiß, dass die Big O-Notation für get ist O (1), und fügen Sie ist O (1) für eine Arraylist, während LinkedList O (n) für get und O (1) für Zusatz ist. Hat der Iterator mit der gleichen Big O-Notation verhalten?

War es hilfreich?

Lösung

Es hängt weitgehend davon ab, ob Sie die maximale Größe jeder Liste wissen vorne.

Wenn Sie das tun, verwenden ArrayList; es wird sicherlich schneller sein.

Ansonsten werden Sie wahrscheinlich Profil haben. Während der Zugang zum ArrayList ist O (1), wodurch es nicht so einfach ist, weil der dynamische Größenanpassung.

Ein weiterer Punkt ist, dass der Raum-Zeit-Kompromiss nicht eindeutig ist. Jedes Java-Objekt hat eine ziemlich wenig Overhead. Während ein ArrayList auf Überschuss Schlitze etwas Platz vergeuden kann, ist jeder Schlitz nur 4 Bytes (oder 8 auf einem 64-Bit-JVM). Jedes Element einer LinkedList ist wahrscheinlich etwa 50 Byte (vielleicht 100 in einem 64-Bit-JVM). Also muss man schon einige verschwendete Schlitze in einem ArrayList haben, bevor ein LinkedList tatsächlich ihren vermeintlichen Raumvorteil gewinnt. Referenzlokalität ist auch ein Faktor, und ArrayList ist es zu bevorzugen.

In der Praxis habe ich fast immer ArrayList verwenden.

Andere Tipps

Erste Gedanken:

  • Refaktorieren Code die Liste nicht benötigen.
  • Vereinfachen Sie die Daten auf eine skalare Datentyp, dann verwenden: int []
  • oder auch nur eine Reihe von verwenden, was auch immer Objekt Sie haben: Object [] - John Gardner
  • Initialisieren Sie die Liste auf die volle Größe: new Arraylist (123);

Natürlich, wie alle anderen zu erwähnen, Performance-Tests tun, beweisen Sie Ihre neue Lösung eine Verbesserung ist.

Iterieren durch eine verkettete Liste ist O (1) pro Element.

The Big O-Laufzeit für jede Option ist das gleiche. Wahrscheinlich wird die Arraylist schneller wegen der besseren Speicherlokalizität, aber man müßte es messen, um sicher zu wissen. Wählen Sie, was macht den Code klarsten.

LinkedList Iterieren kann O (n ^ 2) sein, wenn naiv getan. Im Einzelnen:

List<Object> list = new LinkedList<Object>();
for (int i = 0; i < list.size(); i++) {
    list.get(i);
}

Das ist absolut schrecklich in Bezug auf die Effizienz aufgrund der Tatsache, dass die Liste i durchlaufen werden müssen zweimal für jede Iteration. Wenn Sie LinkedList tun verwenden, müssen Sie entweder eine Iterator oder Java 5 Die erweiterte for-Schleife verwenden:

for (Object o : list) {
    // ...
}

Der obige Code ist O (n), da die Liste zustandsvoll an Ort und Stelle durchlaufen wird.

Um alle der oben genannten Ärger zu vermeiden, nur ArrayList verwenden. Es ist nicht immer die beste Wahl (vor allem für die Raumeffizienz), aber es ist in der Regel eine sichere Wette.

Ich schlage vor, es Benchmarking. Es ist eine Sache, die API zu lesen, aber bis Sie es selbst versuchen, es würde akademisch.

Sollte fair einfach zu testen, so stellen Sie sicher, dass Sie sinnvolle Operationen tun, oder Hotspot wird out-smart Sie und optimieren, um alles zu einem NO-OP:)

Sie wollen an Sicherheit grenzender Wahrscheinlichkeit eine Arraylist . Sowohl das Hinzufügen und Lesen „abgeschrieben konstante Zeit“ (dh O (1)), wie in der Dokumentation angegeben (beachten Sie, dass dies wahr ist, auch wenn die Liste seine Größe erhöhen - es gestaltet ist wie das finden Sie unter http://java.sun.com/j2se/1.5.0/docs /api/java/util/ArrayList.html ). Wenn Sie etwa die Anzahl der Objekte wissen, dass Sie die Speicherung sein dann auch die Arraylist Größenzunahme entfällt.

Das Hinzufügen des Ende einer verketteten Liste ist O (1), aber der konstante Multiplikator größer als Arraylist (da Sie sind in der Regel einem Knoten Objekt jedes Mal zu schaffen). Lesen ist praktisch identisch mit dem Arraylist, wenn Sie einen Iterator verwenden.

Es ist eine gute Regel immer die einfachste Struktur verwenden Sie können, es sei denn, es ist ein guter Grund, nicht zu. Hier gibt es keinen solchen Grund.

Die genaue Zitat von der Dokumentation für Arraylist ist: „. Die Additionsoperation läuft in den fortgeführten Anschaffungs konstante Zeit, das heißt, n Hinzufügen von Elementen erfordert O (n) Zeit Alle anderen Operationen laufen in linearer Zeit (grob gesagt). der konstante Faktor ist gering im Vergleich zu dem für die LinkedList Umsetzung. "

Es gibt eine neue Liste Implementierung namens GlueList das ist schneller als alle klassischen Listenimplementierungen.

Ich habe tatsächlich begonnen zu denken, dass jede Nutzung von Datenstrukturen mit nicht-deterministischem Verhalten, wie Arraylist oder HashMap, sollte vermieden werden, so würde ich nur verwenden Arraylist sagen, wenn man seine Größe gebunden ist; jede unbeschränkte Liste LinkedList verwenden. Das ist, weil ich hauptsächlich Codesysteme mit nahezu Echtzeitanforderungen though.

Das Hauptproblem ist, dass jede Speicherzuweisung (die zufällig mit jeder Addierungsoperation passieren könnte) auch eine Garbage Collection die dazu führen könnte, und jede Garbage Collection kann dazu führen Sie ein Ziel zu verfehlen. Je größer die Zuteilung ist umso wahrscheinlicher dies geschehen kann, und dies wird auch verstärkt, wenn Sie CMS Sammler verwenden. CMS ist nicht Verdichtung, so die Suche nach Platz für einen neuen verknüpften Listenknoten ist in der Regel einfacher sein werde als Platzsuche für eine neue 10.000 Elementanordnung.

Der strengere Ihr Ansatz zur Codierung, desto näher können Sie mit einem Vorrat JVM Echtzeit kommen. Aber nur Datenstrukturen mit deterministischem Verhalten ist die Wahl einer der ersten Schritte, die Sie müßten nehmen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top