Was ist die effizienteste Methode zum initialisieren einer 3D-Vektor?
Ich habe einen 3D-Vektor mit Strings in C++:
vector<vector<vector<string>>> some_vector
Dass ich versuche zu finden ist eine schnelle Methode zum reservieren von Speicher für Sie.
Ich zu definieren versuchte es mit zwei verschiedenen Methoden wie folgt:
#include<vector>
#include<iostream>
#include<ctime>
using namespace std;
#define DIM1 100
#define DIM2 9
#define DIM3 120
int main()
{
clock_t t1_start = clock();
vector<vector<vector<string>>> vec1(DIM1, vector<vector<string>>(DIM2, vector<string>(DIM3)));
clock_t t1_end = clock();
double diff1 = (t1_end - t1_start) / double(CLOCKS_PER_SEC);
clock_t t2_start = clock();
vector<vector<vector<string>>> vec2;
vec2.resize(DIM1);
for(int i = 0; i < DIM1; i++)
{
vec2[i].resize(DIM2);
for(int j = 0; j < DIM2; j++)
vec2[i][j].resize(DIM3);
}
clock_t t2_end = clock();
double diff2 = (t2_end - t2_start) / double(CLOCKS_PER_SEC);
cout<<"1st definition used time: "<<diff1<<"s"<<endl;
cout<<"2nd definition used time: "<<diff2<<"s"<<endl;
}
Ich erwarten, dass die erste Methode (vec1) schneller sein könnte als die 2. (vec2).
Aber es stellte sich heraus, dass die 1. Methode ist viel langsamer als die 2te. Auf meinem Rechner, die 1. Methode verwendet 0.245 Sekunden, während die 2. Methode verwendet 0.152 Sekunden.
Außerdem, wenn ich schalten Sie den Datentyp int, der 1. nahm man 0.058 Sekunden, und die 2. dauerte 0.004.
Kann ich wissen, was die Ursache dieser Differenz? Und ist es besser zuordnen von Speicher für einen 3D-Vektor?
Vielen Dank im Voraus.
- Sind Sie mit einem optimierten bauen?
- Was werden Sie tun, erfordert diese hohe Leistung für die Zuordnung Ihrer Daten Struktur? Wenn Sie etwas benötigen, das super-schnelle, dreidimensionale
std::vector<>
s kann nicht sein, was du bist suchen für. - Wenn die Dimensionen konstant sind, warum dann nicht
std::array<std::array<std::array<std::string, DIM3>, DIM2>, DIM1>
? - Es könnte sein, weil es könnte mehr Kopien in den ersten Aufruf gegen den zweiten Anruf
- Wenn Sie wechseln, um die Reihenfolge der tests, wie wirkt sich das auf das timing? (Und stellen Sie sicher, Optimierungen aktiviert sind.) Erwägen Sie die Verwendung einer bessere benchmarking-tool, verwendet ein high-precision timer und läuft viele Iterationen zu glätten verschiedene cache-und externe Umwelt-Effekte.
- Danke für die Antwort. Dann, welche Art von Datenstruktur, die würden Sie empfehlen?
- Gegeben, dass Sie haben nicht erklärt, warum Sie wollen, dass die Daten-Struktur, wie Sie gehen zu verwenden, oder aus welchem Grund die Initialisierung muss schnell sein, ich dachte, Sie sollten das tun, was die Antwort vorgeschlagen, und verwenden Sie einen einzigen chunk-Speicher haben, können Sie index dreidimensional.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die erste version, konstruiert ein 2-d Vektor, indem Sie eine 1-d-Vektor, und dann baut den 3-d-Vektor durch das kopieren. Dies könnte langsamer sein als die Größe der Vektoren, ohne Sie zu kopieren. Allerdings würde ich hoffen, dass der Unterschied sollte vernachlässigbar sein, wenn Sie Gebäude mit Optimierung.
Könnte es besser sein, zu einem einzigen zusammenhängenden array, eingewickelt in eine Klasse, bietet multi-dimensional-Accessoren verfügen. Dadurch wäre die Zuordnung viel einfacher, und würde auch vermeiden, dass einige Zeiger-Dereferenzierung beim Zugriff auf Elemente (auf Kosten von ein bisschen Arithmetik). So etwas wie dieses:
at
Funktion, und verschiedenen anderen bits und Stücke, mehr zu sein als eine Skizze, wie würden Sie implementieren Ihre eigenen container.Ich denke, ich würde es optimieren, indem Sie Ihr einen großen block Speicher anstelle von vielen kleinen. Dieser ist nur 2D statt 3D, gibt aber die grundlegende Idee:
Für 3D, Sie benötigen, um mit "Ebenen" (oder so) zusammen mit Zeilen und Spalten, aber die Grundidee ist ziemlich das gleiche.
Beim initialisieren einen Vektor der Vektoren in der ersten Methode, einen temporären Vektor zugeordnet ist, und dann kopiert in die äußere Vektor die gewünschte Anzahl von Zeiten. Dies bedeutet, dass Sie eine extra-Zuweisung, die ist unnötig und die neuen Elemente werden initialisiert durch kopieren der Wert aus einer anderen Datenstruktur, die verwendet mehr Speicher zugreift.
Größe der Vektoren gemäß der zweiten Methode wird mehr hässlich, sondern vermeidet die zusätzliche Zuteilung. Des weiteren wurde die neue Elemente werden erstellt, indem der Standardkonstruktor und brauchen nicht zu kopieren von anderen Vektoren. Diese werden auch schneller.
Wenn es auf Geschwindigkeit ankommt (und vielleicht ist es noch nicht, die vorzeitige Optimierung und alles, was), dann müssen Sie die zweite Methode verwenden (ODER ein single-block-Aufteilung, wie vorgeschlagen, durch die anderen Antworten). Ich habe nicht glauben, dass ein compiler kann einfach "optimieren" entfernt die Ineffizienz der ersten Methode.
Initialisierung eines 3D-string-Vektor wird initialisiert den Vektor-Struktur, die für jede dimension und für jeden index, zum Beispiel: