2013-10-04 14 views
7

Welche Methode ist schneller und hat weniger Overhead? 1Löschen eines Vektors oder Definieren eines neuen Vektors, welcher ist schneller

Methode:

void foo() { 
    std::vector<int> aVector; 
    for (int i = 0; i < 1000000; ++i) { 
    aVector.clear(); 
    aVector.push_back(i); 
    } 
} 

Methode 2:

void foo() { 
    for (int i = 0; i < 1000000; ++i) { 
    std::vector<int> aVector; 
    aVector.push_back(i); 
    } 
} 

Sie können sagen, dass das Beispiel sinnlos! Aber das ist nur ein Ausschnitt aus meinem großen Code. Kurz gesagt ich ist es besser,

„erstellen Sie einen Vektor einmal, und deaktivieren Sie es für die Nutzung“ wissen wollen

oder

UPDATE

„einen neuen Vektor jedes Mal schaffen“

Danke für die Vorschläge, habe ich beide getestet und hier sind die Ergebnisse

Methode 1:

$ time ./test1 

real 0m0.044s 
user 0m0.042s 
sys  0m0.002s 

Methode 2:

$ time ./test2 

real 0m0.601s 
user 0m0.599s 
sys  0m0.002s 

den Vektor Clearing ist besser. Vielleicht hilft dies jemand anderen :)

+1

"einen Vektor löschen oder einen neuen Vektor definieren, welcher ist schneller" - benchmarken Sie es und Sie werden es wissen. Es gibt keine allgemeingültige Aussage, da dies von vielen plattform- und implementierungsspezifischen Details abhängt. –

+0

Zustimmen, aber ich möchte wissen, wie g ++ einen optimierten Code für die Methoden generiert. Welche ist besser für Compiler? – mahmood

+2

Ich würde erwarten, dass die "Clear" -Methode schneller ist, wenn es einen Unterschied gibt. –

Antwort

6

Die clear() ist am ehesten schneller, da Sie den Speicher behalten, der für vorherige push_back() s in den Vektor zugeordnet wurde, so dass die Notwendigkeit für die Zuordnung verringert.

Auch Sie weg mit 1 Konstruktor Aufruf und 1 Destruktor Aufruf pro Schleife.

Dies ist alles ignorieren, was Sie Compiler Optimierer mit diesem Code tun könnte.

+0

+1 Das, was ich schreiben wollte. –

0

Um einen leeren Vektor zu erstellen, ist sehr wenig Overhead. WACHSEN eines Vektors auf eine große Größe ist potentiell ziemlich teuer, da er sich jedes Mal verdoppelt - so würde ein 1M-Eintragsvektor 15-20 "Kopien" aus dem aktuellen Inhalt haben.

Für triviale Grundtypen, wie int, ist der Aufwand beim Erstellen eines Objekts und Zerstören des Objekts "nichts", aber für jedes komplexere Objekt müssen Sie die Konstruktion und Zerstörung des Objekts berücksichtigen, was oft wesentlich mehr ist als das "setze das Objekt in den Vektor" und "entferne es aus dem Vektor". Mit anderen Worten, es kommt auf den Konstruktor und den Destruktor für jedes Objekt an.

Für JEDES "was ist schneller von X oder Y" müssen Sie wirklich für die Umstände benchmarken, die Sie verstehen wollen, es sei denn, es ist SEHR offensichtlich, dass man deutlich schneller ist als das andere (wie "lineare Suche oder binäre Suche von X-Elementen ", wobei die lineare Suche proportional zu X ist und die binäre Suche log2 (x) ist.

Weiter bin ich etwas verwirrt über Ihr Beispiel - Speichern von einem Element in einem Vektor ist ziemlich umständlich, und ein gutes Stück Aufwand über int x = i; - Ich nehme an, dass Sie nicht wirklich, dass als Benchmark. Mit anderen Worten, Ihr bestimmter Vergleich ist nicht sehr fair, weil es eindeutig mehr Arbeit macht, 1M-Vektoren zu konstruieren, als einen Vektor zu konstruieren und ihn 1-mal zu füllen und zu löschen.Wenn Sie jedoch Ihren Test in etwa so aus:

void foo() { 
    for (int i = 0; i < 1000; ++i) { 
    std::vector<int> aVector; 
    for(j = 0; j < 1000; j++) 
    { 
     aVector.push_back(i); 
    } 
    } 
} 

[und die entsprechende Änderung des anderen Code] erwarte ich, dass die Ergebnisse wären ziemlich ähnlich sein.

+0

std :: vector reserviert dynamisch Speicher. Wenn dynamische Allokationsroutinen sehr häufig aufgerufen werden (wie in diesem Beispiel), werden sie zu einem großen Engpass, selbst wenn die Daten keine Konstruktoren haben. Da clear() die internen Daten normalerweise nicht verkleinert, ist das Aufrufen von clear schneller. – SigTerm

+0

@SigTerm: Ja, aber Sie können auch 'aVector.resize (1000)' verwenden, um diese Zuordnung zu vermeiden. Aber wie gesagt, es hängt davon ab, was im Vektor gespeichert ist. –

+0

Wenn das Ziel 'push_back' Elemente ist, dann wäre' aVector.reserve (1000) 'genauer. –

Verwandte Themen