Mit den neuesten Trends zu C- und C ++ - Anwendungen und mit den neuesten, ich meine den letzten Jahren, hatte ich erwartet, dass std::allocator
s viel häufiger verwendet werden als es wirklich ist.
Moderne Anwendungen sind in der Regel Multithread-Anwendungen oder in Form von Parallelität und verwalten eine erhebliche Menge an Speicher, insbesondere in einigen Bereichen wie Spielen und Multimedia-Anwendungen. Daher steigen die üblichen hohen Kosten für die Zuweisung / Freigabe und wirken sich noch stärker auf die Leistung aus als bei alten Anwendungen.
Aber für das, was ich sehen kann, ist diese Art der Speicherverwaltung durch std::allocator
s nicht beliebt. Ich kann nicht einmal eine mir bekannte Bibliothek zählen, die eine Begründung für eine standardisierte Art der Speicherverwaltung verwendet.
Es gibt einen echten Grund, warum std::allocator
nicht beliebt ist? Technische Gründe?
quelle
std::allocator
Er ist äußerst einfach zu verwenden.std::allocator
(was im Grunde genommen ein Wrappernew
und eine Platzierung istnew
) nicht so häufig verwendet wird? Oder fragen Sie sich, warum das C ++ - Konzept vonAllocator
nicht weit verbreitet ist? Das sind zwei verschiedene Fragen.Antworten:
Hier gibt es zwei Fragen:
1) Warum wird nicht
std::allocator
mehr verwendet?Die kurze Antwort ist, weil für die meisten Anwendungen die Verwendung
new
unddelete
ausreichend ist.Zunächst ein kurzer Überblick darüber, wofür das C ++ 11 Allocator-Konzept gedacht ist. Wenn Sie a ausführen, wird im Grunde genommen
new Foo
sowohl Speicher zugewiesen als auch das Objekt in diesem Speicher erstellt.Was aber, wenn Sie Speicher zuweisen und in zwei separaten Schritten konstruieren müssen? Das klassische Beispiel hierfür ist
std::vector
, dass Speicher zugewiesen werden kann, ohne ihn sofort zu initialisieren, aber dann die Elemente erstellt, wenn Sie sie dem Container hinzufügen. Der Zweck vonstd::allocator
besteht darin, eine Schnittstelle bereitzustellen, um diese separaten Schritte auf einheitliche Weise auszuführen.Für die meisten Benutzer ist diese Kontrollebene jedoch nicht erforderlich, da dies nur eine weitere Sache ist, die Sie beim Bereinigen Ihrer Ausnahmen beachten müssen.
2) Warum nutzen nicht mehr Dinge das C ++ - Konzept von
Allocator
?Meistens ist die Notwendigkeit nicht da. Die einzigen Klassen, die sie verwenden, sind diejenigen, die ihren Benutzern mehr Kontrolle über die Quelle des von ihnen zugewiesenen Speichers geben möchten. Die Standardbibliothekscontainer sind so geschrieben, dass der Benutzer diese Entscheidungen treffen kann, wenn er dies wünscht. Standardmäßig wird jedoch der normale Allokator verwendet.
quelle
Die Popularität einer Sprache oder eines Bibliothekskonzepts steht in umgekehrter Korrelation mit der zugrunde liegenden Komplexität.
Das
std::allocator
ist ein Low-Level-Konzept und hat als solches potenzielle Fallstricke. Ein benutzerdefinierter Allokator im Voraus zu haben, wird wahrscheinlich als vorzeitige Optimierung eingestuft. Ähnlich wie bei anderen Low-Level-Konzepten wird es im Allgemeinen bevorzugt, das Arbeitszuweisungsmanagement an Bibliotheken (stdlib, boost) zu delegieren, es sei denn, der Aufwand für die Bearbeitung der Komplexität Ihrer eigenen Zuordnungen ist absolut gerechtfertigt.Betrachten Sie Zeiger als nur ein unterstützendes Beispiel für diese These. Wir lieben Zeiger für ihren uneingeschränkten Zugriff auf Speicher und den Null-Overhead, aber in C ++ wissen wir besser, Scoped / Raii-Wrapper zu verwenden, um die Komplexität zu verwalten, das heißt, bis wir die Leistung explizit benötigen oder uns alle auf eine Semantik einigen können, die uns nicht gehört gut definierte Anwendungsfälle.
Wenn Sie einen std :: allocator verwenden, müssen Sie die ABI- und API-Kompatibilität sowie wunderbare Fragen wie das gewünschte Verhalten berücksichtigen, wenn der Code
std::vector<T,A1>().swap(std::vector<T,A2>())
mit verschiedenen (und statusbehafteten!)A1
UndA2
Allokatoren zusammenarbeitet. Außerdem verwenden einige Container den Allokator nicht einmal so, wie Sie es beabsichtigt haben! Schauen Sie sichstd::list<T,A>
oderstd::map<K,T,C,A>
zum Beispiel an. Die natürliche Erwartung ist, dass der Allokator verwendet wird, um Objekte vom TypT
für eine Liste oder einepair<const K,T>
Karte zuzuweisen. In der Praxis fordert eine Standardbibliotheksimplementierung jedoch die Zuweisung einer Liste oder eines Kartenknotens an, und sogar die Größe des Knotens kann sein unterscheidet sich zwischen Release- und Debug-Builds. Benutzerdefinierte Allokatoren sind voller Kleinigkeiten, und die zusätzliche Komplexität und Detailgenauigkeit ist für die gängigsten Programmieraufgaben nicht erforderlich.quelle
std::unique_ptr<T>
um Speicher zu besitzen, im Gegensatz dazuT *
?Ein Allokator ist eine Richtlinie, die von Abhängigkeiten in die Standardcontainer eingefügt wird. Es dient hauptsächlich dazu, dem Client-Code zu ermöglichen, die Zuordnungsrichtlinie von der Instanziierung in bereits implementierten Containern zu trennen .
Das Problem tritt auf, wenn Sie std :: container verwenden müssen und die Standardzuweisungsrichtlinie (wie von std :: allocator implementiert) nicht den Anforderungen Ihres Projekts entspricht (z. B. soll die std :: vector-Implementierung ausgelöst werden, wenn mehr Wenn mehr als 1024 Objekte zugewiesen sind, möchten Sie einen Speicherpool verwenden oder sicherstellen, dass alle Zuordnungen in einem bestimmten Speicherbereich vorab zugewiesen sind usw.).
Wenn Sie keinen anderen Allokator in die Container einfügen könnten, wäre es Ihnen in einigen Projekten untersagt, die std :: -Container insgesamt zu verwenden.
Um dies zu umgehen (und sicherzustellen, dass Sie die std :: -Container weiterhin verwenden können, wenn Sie komplexe Speicheranforderungen haben), ist der Allokator ein Vorlagenparameter für die Container.
Um Ihre Frage zu beantworten : Die meisten Benutzer verwenden keine std :: allocators, da sie beim Schreiben von Clientcode die volle Kontrolle über die Zuweisungen haben - sie müssen also keine Zuweisungsrichtlinie einfügen - und wenn sie Bibliothekscode verwenden, den std :: Allokator ist normalerweise genug.
quelle