2015-11-12 17 views
7

Chciałbym stworzyć wektor jakiegoś złożonego typu, czytając poszczególne elementy ze strumienia. Znam rozmiar wektora z góry. Czy lepiej jest określić liczbę elementów w konstruktorze wektorowym lub przy użyciu metody rezerwy? Który z tych dwóch jest lepszy?Zapełnianie wektora znaną liczbą elementów: określić jego rozmiar w konstruktorze lub przy użyciu metody rezerwy?

int myElementCount = stream.ReadInt(); 
vector<MyElement> myVector(myElementCount); 
for (int i = 0; i < myElementCount; i++) 
{ 
    myVector[i] = stream.ReadMyElement(); 
} 

lub

int myElementCount = stream.ReadInt(); 
vector<MyElement> myVector; 
myVector.reserve(myElementCount); 
for (int i = 0; i < myElementCount; i++) 
{ 
    myVector.push_back(stream.ReadMyElement()); 
} 

Co o przypadku, gdy po prostu utworzyć wektor wskazówki lub jakiś inny typ prosty.

+0

Użyj 'resize()' zamiast 'reserve()', jest to powszechne zamieszanie dla początkujących. –

+3

@ πάνταῥεῖ Dlaczego? Czy "resize" również domyślnie nie tworzy obiektów? OP i tak robi 'push_back'. Może też jestem zdezorientowany :) – vsoftco

Odpowiedz

6

To zależy od tego, co jest MyElement, zwłaszcza to, co robi operator=, więc jest to w dużym stopniu typowe "wypróbuj oba i użyj szybszego dla siebie". Istnieje trzeci wybór, użyj C++ 11 i emplace_back, zwłaszcza jeśli MyElement jest ciężki.

Jako Datapoint na int lub double Okazało się, że za pomocą konstruktora (lub resize()) i [] szybciej. W szczególności w ten sposób pętla jest znacznie łatwiejsza do wektoryzowania przez kompilator.

+2

Komentarz boczny: 'emplace_back' i' push_back' są równoważne na wartościach r (których używa OP), ten ostatni również przenosi obiekt. Ale zgadzam się, że 'emplace_back' wyraźnie określa zamiar. – vsoftco

+0

* "szczególnie co to' operator = 'robi" * - podejście 'push_back' polega na (ewentualnie elided) kopiowaniu konstrukcji elementów (z domyślnym alokatorem, to jest w zasadzie nowe miejsce docelowe), podczas gdy podejście wielkości konstruktora obejmuje domyślną konstrukcję to przypisanie, więc względne koszty wszystkich tych operacji są ważne, tak samo jak to, czy kompilator może zoptymalizować wielokrotne kontrole wydajności i przyrosty wielkości, a następnie wykonać tak wiele operacji rozwijania pętli lub innych optymalizacji .... –