Overhead für die Verwendung von std :: vector?

8

Ich weiß, dass die manuelle Zuweisung dynamischer Speicher im Allgemeinen eine schlechte Idee ist, aber ist es manchmal eine bessere Lösung als die Verwendung von std::vector ?

Um ein grobes Beispiel zu geben, wenn ich ein Array von n ganzen Zahlen speichern müsste, wo n & lt; = 16, sagen wir. Ich könnte es mit

implementieren %Vor%

oder mit einem Vektor:

%Vor%

Ist es absolut immer eine bessere Idee, ein std::vector zu verwenden, oder könnte es praktische Situationen geben, in denen eine manuelle Zuweisung des dynamischen Speichers eine bessere Idee wäre, um die Effizienz zu erhöhen?

    
Vivek Ghaisas 08.03.2013, 12:35
quelle

7 Antworten

11

Es ist immer besser, std::vector / std::array zu verwenden, zumindest bis Sie (durch Profiling) nachweisen können, dass die T* a = new T[100]; -Lösung in Ihrer spezifischen Situation erheblich schneller ist. Dies ist unwahrscheinlich: vector / array ist eine extrem dünne Schicht um ein einfaches altes Array. Es gibt einige Overheads für die Überprüfung mit vector::at , aber Sie können das umgehen, indem Sie operator[] verwenden.

    
us2012 08.03.2013, 12:40
quelle
8

Ich kann mir keinen Fall vorstellen, bei dem ein C-Stil dynamisch zugewiesen wird Vektor macht Sinn. (Ich arbeite seit über 25 Jahren in C ++ Jahre, und ich muss noch new[] verwenden.) Normalerweise, wenn ich das weiß Größe vorne, verwende ich etwas wie:

%Vor%

, um einen bereits großen Vektor zu erhalten, anstatt push_back zu verwenden.

Natürlich, wenn n sehr klein ist und zur Kompilierzeit bekannt ist, Ich werde std::array verwenden (wenn ich Zugriff auf C ++ 11 habe) oder sogar ein C-Stil-Array, und erstellen Sie einfach das Objekt auf dem Stapel mit nein dynamische Zuweisung. (Solche Fälle scheinen in der Code, an dem ich arbeite; kleine Arrays fester Größe sind tendenziell Mitglieder von Klassen. Wo ich gelegentlich ein C-Stil-Array verwende.)

    
James Kanze 08.03.2013 12:58
quelle
4

Wenn Sie die Größe im Voraus wissen (insbesondere zur Kompilierzeit) und die dynamischen Größenanpassungsfunktionen von std::vector nicht benötigen, ist die Verwendung von etwas einfacherem in Ordnung.

Das sollte jedoch vorzugsweise std::array sein, wenn Sie C ++ 11 haben, oder etwas wie boost::scoped_array , sonst.

Ich bezweifle, dass es viel Effizienzgewinn geben wird, wenn es die Code-Größe oder etwas anderes nicht wesentlich reduziert, aber es ist expressiver, was sich sowieso lohnt.

    
Useless 08.03.2013 12:38
quelle
4

Sie sollten versuchen, C -style-arrays in C++ zu vermeiden, wann immer dies möglich ist. Das STL stellt Container zur Verfügung, die normalerweise für jeden Bedarf ausreichen. Stellen Sie sich eine Neuzuordnung für ein Array vor oder löschen Sie Elemente aus der Mitte. Der Container schirmt dich davor ab, dies zu handhaben, während du dich selbst darum kümmern musst, und wenn du das nicht hundertmal getan hast, ist es ziemlich fehleranfällig Eine Ausnahme ist natürlich, wenn Sie Low-Level-Probleme adressieren, die STL -Container möglicherweise nicht bewältigen können.

Es gab bereits einige Diskussionen zu diesem Thema. Siehe hier auf SO.

>     
bash.d 08.03.2013 12:41
quelle
3
  

Ist es absolut immer eine bessere Idee, einen std :: vector zu verwenden, oder könnte es praktische Situationen geben, in denen die manuelle Zuweisung des dynamischen Speichers eine bessere Idee wäre, um die Effizienz zu erhöhen?

Nenn mich einen Dummkopf, aber 99,9999 ...% der Zeiten würde ich einfach einen Standardcontainer benutzen. Die Standardauswahl sollte std::vector sein, aber auch std::deque<> könnte manchmal eine vernünftige Option sein . Wenn die Größe zum Zeitpunkt der Kompilierung bekannt ist, wählen Sie std::array<> , einen einfachen, sicheren Wrapper mit C-artigen Arrays, der keinen Overhead verursacht.

Standardcontainer stellen Memberfunktionen dar, um die anfänglich reservierte Speichermenge anzugeben, so dass Sie keine Probleme mit Neuzuweisungen haben und Sie sich nicht an delete[] in Ihrem Array erinnern müssen. Ich verstehe wirklich nicht, warum man manuelle Speicherverwaltung verwenden sollte.

Effizienz sollte kein Problem sein, da Sie Funktionen zum Werfen und Nichtwerfen von Elementen haben, um auf die enthaltenen Elemente zuzugreifen. Sie haben also die Wahl, ob Sie Sicherheit oder Leistung bevorzugen.

    
Andy Prowl 08.03.2013 12:42
quelle
2

std :: vector könnte mit einem size_type-Parameter konstruiert werden, der den Vektor mit der angegebenen Anzahl von Elementen instanziiert und eine einzelne dynamische Zuweisung (wie Ihr Array) ausführt, und Sie können auch reserve , um die Anzahl der Neuzuweisungen während der Nutzungsdauer zu verringern.

    
Zlatomir 08.03.2013 12:43
quelle
0

In n ist zur Kompilierzeit bekannt, dann sollten Sie std::array als:

wählen %Vor%

und wenn n zur Kompilierzeit nicht bekannt ist ODER das Array zur Laufzeit wachsen kann, dann gehe zu std::vector :

%Vor%

In manchen Fällen bevorzugen Sie möglicherweise auch std::deque , was in einigen Szenarien schneller ist als std::vector . Sehen Sie diese:

Ich hoffe, das hilft.

    
Nawaz 08.03.2013 12:42
quelle