Im folgenden Code musste ich ein Element, ein beliebiges Element, aus toSearch holen. Ich war nicht in der Lage, eine nützliche Methode in der Set-Schnittstellendefinition zu finden, um nur ein einzelnes (zufälliges, aber nicht unbedingt zufälliges) Element der Menge zurückzugeben. Also habe ich die Methode toArray () [0] verwendet (im folgenden Code vorhanden).
%Vor%Die andere Technik, die ich gesehen habe, ist, " (Coordinate) toSearch.toArray () [0] " mit " toSearch.iterator (). next () ". Welche Methode, toArray () oder iterator (), wird am ehesten am schnellsten mit dem geringsten GC-Effekt (Garbage Collection) ausgeführt?
Meine Intuition (nach dem Verfassen dieser Frage) ist, dass die zweite Technik, die den Iterator verwendet, sowohl schneller in der Ausführung als auch weniger Aufwand für den GC ist. Da die Implementierung des übergebenen Sets nicht bekannt ist (unter der Annahme, dass HashSet oder LinkedHashSet am wahrscheinlichsten ist), wie hoch ist der Aufwand in jeder der toArray () - oder iterator () -Methoden? Alle Einsichten dazu würden sehr geschätzt werden.
Fragen (von oben wiederholt):
toSearch.iterator().next()
ist schneller und weniger speicherintensiv, da keine Daten kopiert werden müssen, während toArray
den Inhalt des Satzes dem Array zuordnet und kopiert. Dies ist unabhängig von der tatsächlichen Implementierung: toArray
will immer Daten kopieren.
Nach dem, was ich sehen kann, machen Sie Erste Suche in der Breite
Unten ist das Beispiel, wie es ohne toArray implementiert werden könnte:
%Vor%Implementierungshinweise:
Und jetzt mache ich mir Sorgen, dass die Implementierung der contains () -Methode auf LinkedList bis zu einem vollständigen Scan der Inhalte vor der Rückgabe der Antwort durchgeführt werden kann.
Sie haben Recht mit dem vollständigen Scan (auch lineare Suche genannt). Dennoch, in Ihrem Fall ist es möglich, zusätzliche Set für die Verfolgung bereits besuchter Eckpunkte (BTW, eigentlich ist es Ihr Ergebnis!), Das würde Problem mit enthält Methode in O (1) Zeit zu lösen.
Prost
So würde ich das umsetzen:
%Vor%Anmerkungen:
toSearch
keine eindeutigen Elemente enthalten. LinkedList
für toSearch
bedeutet, dass es eine einfache Methode gibt, um ein Element zu erhalten und es auf einmal zu entfernen. Set.add(...)
eine boolean
zurückgibt, damit die Anzahl der Nachschlagevorgänge in result
festgelegt wird ... im Vergleich zur Verwendung von Set.contains()
. HashSet
anstelle von LinkedHashSet
für die Ergebnisse zu verwenden ... es sei denn, Sie müssen die Reihenfolge kennen, in der die Koordinaten durch die Füllung hinzugefügt wurden. ==
zum Vergleich von Value
Instanzen ist möglicherweise ein bisschen schwierig. Nach Petros Antwort kopierte ich die Methode und führte sie nach seinen Vorschlägen neu ein. Es sieht so aus:
%Vor%Beim Wechsel von "Setzen" in "Warteschlange" wurden meine Effizienzfragen auf die neue bedingte Prüfung verschoben, die ich hinzufügen musste: " if (! toSearch.contains (coordinateAdjacent)) ". Mit der Set-Schnittstelle verhinderte ich, dass Duplikate hinzugefügt wurden. Unter Verwendung der Warteschlangenschnittstelle muss ich überprüfen, dass ich kein Duplikat hinzufüge.
Und jetzt mache ich mir Sorgen, dass die Implementierung der contains () -Methode auf LinkedList bis zu einem vollständigen Scan der Inhalte vor der Rückgabe der Antwort durchgeführt werden kann. Also, vergleichen Sie diese Methode mit der, die ich ursprünglich gepostet habe, die wahrscheinlich effizienter sein wird (bevor ich eine Menge Zeit damit verbringe, die empirischen Tests zu machen)?
Okay, unten ist meine letzte Implementierung mit Feedback (hauptsächlich von Stephen, Cameron und Petro), die das vollständige Eliminieren des toArray () [] - vs-interator (). next () Konflikts beinhaltet. Und ich habe Kommentare eingestreut, um genauer zu unterscheiden, was passiert und warum. Und um besser zu verdeutlichen, warum ich konkret Petro's ursprünglichen Ratschlag "Benutze ein Tracking-Set" umgesetzt habe (unterstützt von Cameron). Und gleich nach dem Codeausschnitt werde ich es mit den anderen vorgeschlagenen Lösungen gegenüberstellen.
%Vor%Ich habe die Methode auf mehrere wichtige Arten aktualisiert:
Die Lösungen von Petro und Stephan besuchen die Koordinaten, die den Wert enthalten, nur einmal, müssen aber die Koordinaten, die den! -Wert mehr als einmal enthalten, erneut aufrufen, was zu mehreren doppelten Fetches / Wertüberprüfungen für Bereiche führen kann, die aus langen labyrinthartigen Tunneln bestehen. Während "lange labyrinthartige Tunnel" als pathologischer Fall angesehen werden können, ist es typischer für die spezielle Domäne, für die ich diese Methode brauche. Und meine "zweite" versuchte Lösung (die hatte die schlechte Leistung LinkedList enthält () Anruf) war fraglich als eine echte Antwort (Stephen zu diesem Thema).
Vielen Dank für Ihr Feedback.
Als nächstes gibt es viele empirische Tests mit einzelnen Variationen / Änderungen über Hunderte von Millionen von Aufrufen. Ich werde diese Antwort irgendwann dieses Wochenende mit Details aktualisieren.
Tags und Links java performance set iterator toarray