Gibt es praktische Einschränkungen nur std :: string statt char-Arrays und std :: vector / Liste anstelle von Arrays in C ++ verwenden?

StackOverflow https://stackoverflow.com/questions/801385

Frage

Ich verwende Vektoren, Listen, Streicher und wstrings obsessiv in meinem Code. Gibt es irgendwelche Fang 22s beteiligt das sollte mich mehr daran interessiert, bei der Verwendung von Arrays von Zeit zu Zeit, Zeichen und wchars statt?

Grundsätzlich, wenn in einer Umgebung arbeiten, die die Standard-Template-Bibliothek unterstützt, ist es jedenfalls die primitiven Typen ist eigentlich besser?

War es hilfreich?

Lösung

Für 99% der Zeit und für 99% der Implementierungen Standard Library, werden Sie, dass std finden :: Vektoren schnell genug sein wird, und die Bequemlichkeit und Sicherheit, die Sie verwenden, sie bekommen mehr als jede kleine Leistung Kosten aufwiegen.

Für die sehr seltenen Fällen, wenn Sie wirklich Bare-Metal-Code benötigen, können Sie einen Vektor wie ein C-Stil-Array behandeln kann:

vector <int> v( 100 );
int * p = &v[0];
p[3] = 42;

Die C ++ Standard garantiert, dass Vektoren aneinander angrenzend zugeordnet sind, so ist dies garantiert zu arbeiten.

In Bezug auf Strings, wird der Convenience-Faktor almnost überwältigend, und die Performance-Probleme neigen dazu, weg zu gehen. Wenn Sie beack zu C-Strings gehen, werden Sie auch die Verwendung von Funktionen wie strlen zurück (), die von Natur aus sehr sich ineffiziente.

Wie für Listen, sollten Sie überlegen sich zweimal, und wahrscheinlich dreimal, bevor sie überhaupt mit, ob Sie eine eigene Implementierung oder der Standard. Die überwiegende Mehrheit der Rechenprobleme besser wird mit einem Vektor / Array gelöst. Der Grund Listen erscheinen so oft in der Literatur ist zu einem großen Teil, weil sie eine bequeme Datenstruktur für Lehrbuch und Schulung Autoren sind zu verwenden, Zeiger und dynamische Zuordnung in einem Rutsch zu erklären. Ich spreche hier als Ex Ausbildung Schriftsteller.

Andere Tipps

ich STL-Klassen halten würde (Vektoren, Strings, etc.). Sie sind sicherer, einfacher zu bedienen, produktiver mit weniger Wahrscheinlichkeit Speicherlecks zu haben und, AFAIK, machen sie einige zusätzliche, Laufzeit von Grenzen überprüft, zumindest bei DEBUG Zeit (Visual C ++).

Dann messen die Leistung. Wenn Sie den Engpass (n) auf STL-Klassen identifizieren, dann C Strings und Arrays Nutzung bewegen.

Aus meiner Erfahrung, sind die Chancen, den Engpass auf Vektor oder String-Nutzung haben, sind sehr gering.

Ein Problem ist der Aufwand, wenn Elemente zugreifen. Selbst mit Vektor und Zeichenfolge, wenn Sie ein Element von Index zugreifen müssen Sie zuerst die Pufferadresse abgerufen werden, dann fügen Sie den Offset (Sie es nicht manuell tun, aber der Compiler gibt einen solchen Code). Mit rohen Array haben Sie bereits die Pufferadresse. Diese zusätzliche Indirektion zu erheblichen Mehraufwand in bestimmten Fällen führen kann und unterliegt Profilierung, wenn Sie die Leistung verbessern wollen.

Wenn Sie keine Echtzeit-Antworten benötigen, bleiben mit Ihrem Ansatz. Sie sind sicherer als Zeichen.

Sie können gelegentlich Szenarien begegnen, wo man ein paar Sachen bessere Leistung oder Speichernutzung bekommen von selbst zu tun (zB std :: string typischerweise etwa 24 Byte Overhead, 12 Bytes für die Zeiger in den std :: string selbst hat und ein Kopfblock auf seinem dynamisch zugewiesenen Stück).

Ich habe an Projekten gearbeitet, wo die Umwandlung von std :: string char * gespeichert merk Speicher (10 der von MB) konst. Ich glaube nicht, diese Projekte sind, was Sie nennen würde typisch.

Oh, STL Ihre Kompilierungszeiten, und irgendwann verletzt, die ein Problem sein kann. Wenn Ihr Projektergebnisse in über einem GB-Objektdateien an den Linker übergeben wird, möchten Sie vielleicht überlegen, wie viel von der Vorlage aufblasen ist.

Ich habe an mehreren Projekten gearbeitet, wo die Speicher-Overhead für Streicher problematisch geworden ist.

Es ist eine Überlegung wert, im Voraus, wie Ihre Anwendung skaliert werden muss. Wenn Sie eine unbegrenzte Anzahl von Strings zu speichern, const char*s zu einem global verwalteten String-Tabelle verwenden, können Sie große Mengen an Speicher speichern.

Aber im Allgemeinen, auf jeden Fall STL-Typen verwenden, es sei denn es einen sehr guten Grund ist es anders zu machen.

Ich glaube, dass die Standard-Speicherzuweisung Technik ein Puffer für Vektoren und Strings ist eine, die jedes Mal die doppelte Menge an Speicher reserviert die aktuell zugewiesenen Speicher verbraucht wird. Dies kann verschwenderisch sein. Sie können ein benutzerdefiniertes allocator natürlich bieten ...

Die andere Sache ist gegen Haufen stapeln zu betrachten. Staticly Größe Arrays und Strings können auf dem Stapel sitzen, oder zumindest der Compiler Griffe für Sie die Speicherverwaltung. Neuere Compiler behandelt dynamische Größe Arrays auch für Sie, wenn sie die entsprechende C99 / C ++ 0x-Funktion bieten. Vektoren und Zeichenketten werden immer den Heap verwenden, und dies kann zu Leistungsproblemen vorstellen, wenn Sie wirklich enge Grenzen haben.

Als Faustregel Gebrauch was es schon, wenn es Ihr Projekt mit seiner Geschwindigkeit / Speicher-Overhead tut weh ... werden Sie wahrscheinlich, dass für 99% der Sachen finden die STL bereitgestellten Klassen sparen Sie Zeit und Mühe, mit wenig bis gar keine Auswirkungen auf Ihre Anwendungen Leistung. (Das heißt "vermeiden vorzeitige Optimierung")

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top