(Dies ist per se keine Spielprogrammierung, aber ich bin mir sicher, wenn ich dies auf SO frage, würde ich angewiesen, nicht vorzeitig zu optimieren, obwohl uns die Geschichte sagt, dass sich jedes große Spiel um diese Dinge Sorgen macht.)
Gibt es irgendwo ein Dokument, in dem die Unterschiede in der Leistung und insbesondere in der Speichernutzung zwischen verschiedenen C ++ - Standardbibliotheksimplementierungen zusammengefasst sind? Die Details einiger Implementierungen sind durch NDA geschützt, aber ein Vergleich zwischen sogar STLport vs. libstdc ++ vs. libc ++ vs. MSVC / Dinkumware (vs. EASTL?) Scheint immens nützlich zu sein.
Insbesondere suche ich nach Antworten auf Fragen wie:
- Wie viel Speicheraufwand ist mit den Standardcontainern verbunden?
- Welche Container führen dynamische Zuweisungen nur durch, indem sie deklariert werden?
- Kann std :: string beim Schreiben kopiert werden? Kurzstringoptimierung? Seile?
- Verwendet std :: deque einen Ringpuffer oder ist es Mist?
deque
in der AWL immer mit einem Vektor implementiert wurde.Antworten:
Wenn Sie eine solche Vergleichstabelle nicht finden, können Sie den betreffenden STL-Klassen auch einen eigenen Allokator hinzufügen und eine Protokollierung hinzufügen.
Die von mir getestete Implementierung (VC 8.0) verwendet keine Speicherzuordnung, indem lediglich ein String / Vektor / Deque deklariert wird, sondern listet und ordnet dies zu. Die Zeichenfolge hat eine Kurzzeichenfolgenoptimierung, da das Hinzufügen von 3 Zeichen keine Zuordnung ausgelöst hat. Die Ausgabe wird unterhalb des Codes hinzugefügt.
Bisher VC8 und STLPort 5.2 getestet, hier ist der Vergleich (im Test enthalten: String, Vektor, Deque, Liste, Karte)
VC8-Ausgabe-String / Vektor / Deque / Liste / Karte:
STLPort 5.2. Ausgabe mit VC8 kompiliert
EASTL- Ergebnisse, keine Deque verfügbar
quelle
std::string
kopiert nicht beim schreiben. Früher war CoW eine Optimierung, aber sobald mehrere Threads in das Bild einfließen, ist eine Pessimisierung nicht mehr möglich - es kann den Code durch massive Faktoren verlangsamen. Es ist so schlimm, dass der C ++ 0x-Standard ihn aktiv als Implementierungsstrategie verbietet. Nicht nur das, sondern die Zulässigkeitstd::string
, veränderbare Iteratoren und Zeichenreferenzen auszuteilen, bedeutet, dass "Schreiben" fürstd::string
fast jede Operation erforderlich ist.Die Optimierung für kurze Zeichenfolgen umfasst, glaube ich, etwa 6 Zeichen oder etwas in dieser Region. Seile sind nicht erlaubt. Sie
std::string
müssen zusammenhängenden Speicher für diec_str()
Funktion . Technisch könnte man sowohl eine zusammenhängende Schnur als auch ein Seil in derselben Klasse halten, aber niemand hat es jemals getan. Darüber hinaus wäre es nach meinem Wissen über Seile unglaublich langsam, sie fadensicher zu manipulieren - vielleicht genauso schlimm oder schlimmer als CoW.Keine Container weisen Speicher zu, indem sie in modernen STLs deklariert werden. Knotenbasierte Container wie list und map haben dies früher getan, jetzt haben sie eine eingebettete Endoptimierung und brauchen sie nicht mehr. Es ist üblich, eine Optimierung namens "Swaptimization" durchzuführen, bei der Sie mit einem leeren Container tauschen. Erwägen:
Natürlich ist dies in C ++ 0x redundant, aber in C ++ 03, als dies üblicherweise verwendet wurde, verringert MahVariable die Effektivität, wenn Speicher bei der Deklaration zugewiesen wird. Ich weiß, dass dies für schnellere Neuzuordnungen von Containern wie
vector
in der MSVC9-STL verwendet wurde, wodurch das Kopieren der Elemente überflüssig wurde.deque
verwendet etwas, das als nicht aufgerollte verknüpfte Liste bezeichnet wird. Grundsätzlich handelt es sich um eine Liste von Arrays, in der Regel mit fester Knotengröße. Als solche für die meisten Anwendungen, behält es die Vorteile beider Zugang structures- Daten zusammenhängenden und fortgeführten Anschaffungs O (1) Entfernung und sowohl vorne hinzufügen zu können und zurück und besser Iterator Ungültigkeits alsvector
.deque
kann aufgrund seiner algorithmischen Komplexität und der Garantie für die Ungültigmachung von Iteratoren niemals durch Vektoren implementiert werden.Wie viel Speicheraufwand ist damit verbunden? Nun, ehrlich gesagt, ist das eine wertlose Frage. Die STL-Container sind so konzipiert, dass sie effizient sind, und wenn Sie ihre Funktionalität replizieren, erhalten Sie entweder eine schlechtere Leistung oder sie befinden sich wieder an derselben Stelle. Wenn Sie die zugrunde liegenden Datenstrukturen kennen, wissen Sie, wie viel Arbeitsspeicher sie verbrauchen, geben oder nehmen, und dies ist nur aus einem guten Grund, z. B. bei der Optimierung kleiner Zeichenfolgen, mehr.
quelle
std::string
Zeit der Fall war . Dafür müssen Sie nicht die neuesten und besten STL-Implementierungen verwenden. msdn.microsoft.com/en-us/library/22a9t119.aspx sagt "Wenn ein Element an der Vorderseite eingefügt wird, bleiben alle Referenzen gültig". Ich bin mir nicht sicher, wie ich das mit einem Umlaufpuffer umsetzen soll, da die Größe geändert werden muss, wenn der Puffer voll ist.Wenn das wirklich deine Frage ist (was mit Sicherheit nicht der Fall ist) die Antwort ist, die Sie in Ihrem eigentlichen Fragentext formuliert haben und die in 4 Fragen endete, von denen keine die Frage stellte, wo Sie eine Ressource finden könnten), lautet die Antwort einfach:
Es gibt keinen.
Die Mehrheit der C ++ - Programmierer muss sich nicht so sehr um den Overhead von Standardbibliotheksstrukturen und die Cache-Leistung von ihnen kümmern (was hoch ist) ohnehin Compiler abhängig ist) oder dergleichen kümmern. Ganz zu schweigen davon, dass Sie normalerweise nicht Ihre Standard-Bibliotheksimplementierung auswählen müssen. Sie verwenden, was mit Ihrem Compiler kommt. Selbst wenn es einige unangenehme Dinge tut, sind die Möglichkeiten für Alternativen begrenzt.
Es gibt natürlich Programmierer, die sich für so etwas interessieren. Aber alle haben vor langer Zeit geschworen, die Standardbibliothek zu benutzen.
Sie haben also eine Gruppe von Programmierern, die sich einfach nicht darum kümmern. Und eine andere Gruppe von Programmierern, denen es egal wäre, ob sie es verwenden, aber da sie es nicht verwenden, ist es ihnen egal. Da es niemanden interessiert, gibt es keine wirklichen Informationen über solche Dinge. Es gibt hier und da informelle Patches mit Informationen (Effective C ++ enthält einen Abschnitt über die Implementierung von std :: string und die großen Unterschiede zwischen diesen), aber nichts Umfassendes. Und auf jeden Fall nichts aktuelles.
quelle