array oder vector
-
Hallo
ich bin gerade auf std::vector gestoßen und frage mich ab wann/wo es sinn macht ihn gegenüber einem Array zu verwenden?
Wird die Reservierung neuer Elemente dabei automatisch auf dem Heap vorgenommen?
Wie groß sind die Geschwindigkeitseinbußen gegenüber einem normalen Array wenn man darauf lesend zugreift?
-
Ich setze std::vector fast überall ein, wo ich arrays benötige (ausser bei kleinen Arrays, deren Größe ich zur Compile Time kenne). std::vector legt die Elemente dynamisch auf dem Heap an, da kann es im Vergleich zu statischen Arrays zu geringfügigen Geschwindigkeitseinbußen kommen. Im Vergleich zu dynamisch erzeugten Arrays dürfte der Geschwindigkeitsunterschied nicht messbar sein.
-
Ich würde prinzipiell
std::vector
einem Array vorziehen (oderstd::tr1::array
, wenn die Grösse wirklich zur Kompilierungszeit bekannt ist) und nur wenn du dir ganz sicher bist, dass du ein Array brauchst eines nehmen.Meistens will man ja sowieso die Grösse noch dynamisch ändern und da ist der vector ideal. Der Speicher wird dynamisch (also Heap) allokiert ja.
In optimiertem Zustand wirst du kaum einen Performanceverlust merken. Bemerkbar wird sich das kaum irgendwo machen.
-
Ich benutze eigentlich fast "nie" arrays
bin faul (später etwaige Fehler zu suchen). Da ich mir nicht zutraue, besser zu optimieren als der Compiler nutze ich lieber std::vector<irgendwas> oder QVector<wasQiges> als mir die Bürde der Speicherverwaltung selbst aufzuerlegen. Soweit ich std::vector verstehe wird im Fall von
#include <vector> int main () { std::vector<int> integs; }
eine bestimmte, mir unbekannte Anzahl von ints als Platz irgendwo reserviert (das macht der Vector für mich irgendwie). Wenn ich nun mehr als den vom vector derzeit reservierten Platz nutze, wird alles an eine neue Stelle kopiert und dabei gleich etwas mehr Platz als zZ benötigt reserviert (da gibts es ganze Bücher drüber wie man zukünftige Anforderungen schedulen sollte).
Was Zeit kostet sind diese Umkopierungen ... wenn du weisst das du jetzt 20000 neue Werte einfügen willst ist ein vorheriges
integs.reserve(integs.size()+20000));
sinnvoll. (oder gleich mit der maximalen Anzahl aufrufenstd::vector<int> integs(24000)
;Das alles könntest du dir einfachst http://www.cplusplus.com/reference/stl/vector/ nachlesen ... da steht auch was zur Performanz.
-
cpp_neuling schrieb:
ich bin gerade auf std::vector gestoßen und frage mich ab wann/wo es sinn macht ihn gegenüber einem Array zu verwenden?
Das leitet sich größtenteils schon von der Schnittstelle ab. std::vector ist "dynamisch" in dem Sinne, dass die Zahl der Elemente zur Laufzeit festgelegt und geändert werden kann und dass die Elemente im Freispeicher leben (typischerweise, kommt auf den Allocator an) -- also physikalisch nicht direkt im vector-Objekt enthalten sind, sondern nur "logisch" (per Zeiger referenziert).
Dagegen gibt es std::tr1::array<T,N> welches direkt N Elemente des Typs T in einem Array speichert, so dass sizeof(std::tr1::array<T,N>) von N abhängt. Dieses Klassentemplate bietet auch eine STL-kompatible Schnittstelle an (Iteratoren u.s.w.) und Objekte vom Typ std::tr1::array<T,N> lassen sich kopieren und zuweisen.
Dann gibt es noch die "rohen Arrays". Diese sind praktisch für statische Lookup-Tables und String-Literale. Es gibt aber Sonderregeln und Irregularitäten. ZB kann man sie nicht so einfach zuweisen/kopieren:
int main() { int a[5] = {1,2,3,4,5}; int b[5] = a; // GEHT NICHT! }
und als (top-level) Parametertyp in Funktionen gibt es sie gar nicht. Sie werden automatisch zu Zeigern konvertiert:
void foo(int c[5]); // <-- a ist hier kein Array, sondern ein // Zeiger und die 5 wird ignoriert
cpp_neuling schrieb:
Wird die Reservierung neuer Elemente dabei automatisch auf dem Heap vorgenommen?
Wenn Du damit den Freispeicher meinst, ja.
cpp_neuling schrieb:
Wie groß sind die Geschwindigkeitseinbußen gegenüber einem normalen Array wenn man darauf lesend zugreift?
Im Release-Modus ist der Overhead gleich Null. Wenn nicht, taugt Dein Compiler / Deine StdLib nichts.
Klassentemplates wie std::vector und std::tr1::array bieten aber eventuell einen Debug-Modus an (siehe Dokumentation Deines Compilers/Deiner StandardLib). So lassen sich zB Pufferüberlauf oder Indizierungsfehler früh erkennen, was bei normalen rohen Arrays nicht so einfach geht.
kk