2014-12-30 7 views
5

Ich bin auf der Suche nach einigen Zeigern, wie Sie einen benutzerdefinierten Zuordner implementieren, der mit einem std::map verwendet werden soll. Ich bin daran interessiert, eine Karte mit Millionen von Einträgen zu füllen, ohne eine Zuordnung für jedes Element im Container zu haben (dies ist der Standardwert für diesen Container). Der Grund dafür ist, Daten an eine Drittanbieter-Bibliothek zu übergeben, die eine Karte verwendet, um Stichproben eines Diagramms (QCustomPlot) zu speichern, und ich fühle den Leistungseinbruch beim Plotten großer Zeitreihen.Wie implementiert man einen benutzerdefinierten Zuordner, der mit std :: map verwendet werden soll?

Ist es möglich, dies mit einer Zuweisung zu tun, wenn die Größe der std::map im Voraus bekannt ist?

EDIT: Die Knoten werden in aufsteigender Reihenfolge in den Container eingegeben.

+0

Vielleicht beantwortet das Ihre Frage? http://stackoverflow.com/questions/13049340/initializing-a-stdmap-when-the-size-is-known-in-advance –

+1

Es ist möglich, aber bedenken Sie, dass die erforderliche Größe wird nicht '(sizeof (Key) + sizeof (Wert)) * num_elem'. Sie müssen bis zu einem gewissen Grad überzuordnen, weil eine der ersten Dinge, die eine 'map' tut, [' rebind_alloc'] (http://en.cppreference.com/w/cpp/memory/allocator_traits) zu einigen ist Interner Baumknotentyp, der verwendet wird, um jedes Element zu halten. Ansonsten wäre mein Rat, die Dokumente "std :: allocator" und "std :: allocator_traits" zu lesen und dann zu sehen, wie Sie stdlib das erste implementiert (vorausgesetzt, Sie finden kein Tutorial zu diesem Thema). – Praetorian

+1

Dinge, die auf Graphen angezeigt werden, sind normalerweise sequentiell, also ist boost :: flat_map (es ist ein sortierter Vektor unter der Haube) besser als std :: map. –

Antwort

1

Die einzige Sache, die ein benutzerdefinierter Zuordner in diesem Fall tun kann, wäre, einen Teil des vom Allocator verursachten Overheads durch Alignment zu vermeiden, wenn Sie die endgültige Größe und den Overhead von std :: map aufgrund von intern kennen Zeiger, Sie könnten einen Puffer mit der erforderlichen Größe reservieren und im benutzerdefinierten Zuordner den gesamten zusammenhängenden Speicher verwenden.

Die Menge an Speicher, die gespeichert werden würde, hängt von den Typen ab, die Sie auf Ihrer Karte verwenden, und ich denke nicht, dass dies so viel ist.

Wie Öö Tiib zu den Kommentaren erwähnt und dau_sama Ihre beste Wette ist boost :: flat_map, oder Sie können es einfach tun benutzerdefinierte über eine

std::vector<std::pair<Key,Value>> 

Wie auch immer, wenn Sie die lib 3rd party ändern und es akzeptiert nur eine std :: map, die Sie immer noch Pech hätten, es sei denn, es akzeptiert einen Typ von Iterator, den Sie anpassen können.

Verwandte Themen