Welche container zum speichern von eindeutigen Werten?

Ich habe Folgendes problem. Ich habe ein Spiel läuft durchschnittlich 60 frames pro Sekunde. Jeder frame muss ich zum speichern von Werten in einen container und es dürfen keine Duplikate.

Es wahrscheinlich zu speichern hat weniger als 100 Elemente pro Bild, aber die Anzahl von insert-Aufrufe werden sehr viel mehr (und vielen abgelehnt, weil es muss eindeutig sein). Erst am Ende des Rahmens brauche ich, um die traverse container. So etwa 60 Iterationen der container pro Rahmen, aber viel mehr Einfügungen.

Beachten Sie die Elemente, die zu speichern sind einfache integer.

Gibt es eine Reihe von Containern, die ich nutzen kann, aber ich kann nicht machen meiner Meinung nach was zu Holen. Leistung ist die zentrale Frage für diese.

Einige pros/cons, die ich gesammelt habe:


Vektor

  • (PRO): Contigous-Speicher, eine große Rolle.
  • (PRO): Speicher reserviert werden kann zunächst, nur sehr wenige Zuweisungen/deallocations danach
  • (CON): Keine alternative, als um die traverse container (std::find) jedes insert() zu finden, eindeutige Schlüssel? Der Vergleich ist einfach, aber (ganze zahlen) und der ganze container können wahrscheinlich passen die cache

set

  • (PRO): Einfach, klar bedeutete für diese
  • (CON): Nicht-Konstante einfügen-Zeit
  • (CON): eine Menge von Zuweisungen/deallocations pro frame
  • (CON): Nicht contigous-Speicher. Traversieren einer Reihe von Hunderten von Objekten bedeutet springen um eine Menge im Speicher.

unordered_set

  • (PRO): Einfach, klar bedeutete für diese
  • (PRO): Mittlerer Fall konstanter Zeit einfügen
  • (CON): Sehen, wie ich es speichern Ganzzahlen, hash-operation wird wahrscheinlich viel teurer als alles andere
  • (CON): eine Menge von Zuweisungen/deallocations pro frame
  • (CON): Nicht contigous-Speicher. Traversieren einer Reihe von Hunderten von Objekten bedeutet springen um eine Menge im Speicher.

Ich bin stützte sich auf, geht die vector-route, da der memory-access-patterns, obwohl eingestellt ist eindeutig gemeint für dieses Problem. Das große Problem ist, dass mir unklar ist, ob das Durchlaufen des Vektors, der für jedes insert ist teurer als die Zuweisungen/deallocations (vor allem wenn man bedenkt, wie oft dies getan werden muss) und die Speicher-lookups von set.

Ich weiß, letztendlich kommt es darauf an das profiling jeden Fall, aber wenn es nichts anderes als ein Vorsprung oder nur theoretisch, was würde wohl am besten in diesem Szenario? Gibt es irgendwelche vor - /Nachteile, die ich vielleicht übersehen habe aswell?

EDIT: Wie ich nicht erwähnen, wird der container gelöscht wird() am Ende von jedem Rahmen

Messen. Gegeben, dass unordered_set ist die - Klassiker "set" - container, mit ungeordneten,-keine-doppelten Semantik und beste asymptotische Komplexität, ich würde give it a shot, aber die Chancen sind vector schlagen wird es für kleine Gebindegrößen, da es weit bessere cache-Lokalität Eigenschaften.
Was über die Bereitstellung Ihrer eigenen allocator, dass in der Lage ist, zu überwinden, die Ineffizienz in der Speicherverwaltung? (z.B. Bereitstellung einer Objekt-pool)
Was auch immer Sie tun, versuchen Sie, richtig zu Kapseln Sie den code und verwenden auto zu track-Typen, so können Sie leicht ändern Sie Ihre Wahl der Behälter in die Zukunft. Dann Messen.
Wenn Sie wissen, welchen Bereich der Werte werden gespeichert in dem Vektor-Sie könnten Sie dort eigene Vektor und verwenden Sie dann random_suffle auf den container und nehmen Sie nur die ersten 100 Elemente aus.
Ein set wird wohl dominiert von Zweig mispredictions. Die kompletten Daten passt in L1 und Zuordnungen vermieden werden können (block-Zuweisung). Allerdings set ist eine Baum-Struktur, so dass mehrere Filialen mit eine ~50% chance misprediction pro legen Sie unvermeidbar sind.

InformationsquelleAutor KaiserJohaan | 2015-02-27

Schreibe einen Kommentar