Was ist die schnellste Sammlung in Java?
Ich brauche nur die Operationen zum Hinzufügen und Entfernen, die Reihenfolge ist nicht wichtig, gleich Elemente sind kein Problem, nichts anderes als Hinzufügen und Entfernen ist wichtig.
Ohne Begrenzung ist auch die Größe wichtig.
Diese Sammlung enthält Objekte in ihm.
Derzeit verwende ich ArrayDeque, da ich sehe, dass dies die schnellere Queue-Implementierung ist.
java
performance
collections
Renato Dinhani
quelle
quelle
Antworten:
ArrayDeque
ist das Beste. Sehen Sie sich diesen Benchmark an , der aus diesem Blog-Beitrag über die Ergebnisse des Benchmarking stammt.ArrayDeque
Es gibt weder den Overhead für KnotenzuweisungenLinkedList
noch den Overhead für die Verschiebung des Array-Inhalts, der beim Entfernen übrig bleibtArrayList
. Im Benchmark ist die Leistung etwa dreimal so hoch wieLinkedList
bei großen Warteschlangen und sogar etwas besser alsArrayList
bei leeren Warteschlangen. Um die beste Leistung zu erzielen, sollten Sie ihm eine Anfangskapazität geben, die groß genug ist, um die Anzahl der Elemente zu speichern, die wahrscheinlich gleichzeitig gespeichert werden, um viele Größenänderungen zu vermeiden.Zwischen
ArrayList
undLinkedList
, so scheint es , dass es auf der durchschnittlichen Anzahl der Gesamt Elemente hängt die Warteschlange zu einem bestimmten Zeitpunkt enthält und dassLinkedList
SchlägeArrayList
bei etwa 10 Elementen beginnen.quelle
ArrayList
wäre ungefähr gleichwertig, obwohlArrayDeque
Javadoc darauf hinweist, dass es möglicherweise etwas schneller ist. Und ja, angesichts der Anforderungen in der Frage würde eine stapelartige Verwendung gut funktionieren. Der Benchmark war jedoch speziell für die Verwendung in der FIFO-Warteschlange vorgesehen (ein Beispiel für den Code finden Sie im verlinkten Blog-Beitrag).Sie können a verwenden
java.util.LinkedList
- es ist doppelt verknüpft und cicrular, also ist das Hinzufügen zu einem Ende und das Nehmen vom anderen O (1)Egal für welche Implementierung Sie sich entscheiden, beziehen Sie sich auf die
Queue
Benutzeroberfläche, damit Sie sie leicht ändern können, wenn sich herausstellt, dass sie nicht zu Ihrem Fall passt (wenn Sie natürlich zuerst eine Warteschlange benötigen).Update: Colins Antwort zeigt einen Benchmark, der zu dem Schluss kommt, dass dies
ArrayDeque
besser ist. Beide haben O (1) -Operationen,LinkedList
erstellen jedoch neue Objekte (Knoten), die die Leistung geringfügig verbessern. Da beide O (1) haben, denke ich nicht, dass es zu falsch wäre, eine Wahl zuLinkedList
treffen.quelle
ArrayDeque
ist objektiv besser.ArrayDeque
ist O (1) zum Hinzufügen und Entfernen am Front / End (dh bei Verwendung als Warteschlange oder Stapel), da es sich um ein kreisförmiges Array handelt und in diesen Fällen nichts kopiert. Darüber hinaus ist die Größenänderung eine gelegentliche Operation, die häufig mit einer geeigneten Anfangskapazität vermieden werden kann.LinkedList
Der Aufwand für eine zusätzliche Objekterstellung (plus Speicherbereinigung dieses Objekts) wirkt sich auf jedes Hinzufügen / Entfernen in der Warteschlange aus. Der von mir verknüpfte Benchmark zeigt, dass er konstant dreimal so schnell ist wie einLinkedList
.O(1) != O(1)
.O()
ist nur ein Maß für die Komplexität, nicht für die Ausführungszeit. Eine Operation, die unabhängig davon immer 5 Jahre dauert,n
istO(1)
ebenso wie eine Operation, die immer 5 ms dauert. Ich würde lieber die verwenden, die 5 ms dauert. Sogar eine Operation, die 5 ms pro Element dauert (was istO(n)
), ist besser als die 5-Jahres-Operation, wennn
sie nicht zu groß wird.ConcurrentLinkedDeque ist die beste Wahl für Multi-Thread-Warteschlangen
quelle