Array oder std::vector?
-
Artchi schrieb:
array<int, 3> a = {1,2,3};Sorry, wenns nicht hierher gehört, aber wie ist das denn implementiert. Sprich welche Operatoren muss man für sowas überladen?
-
bluecode schrieb:
Artchi schrieb:
array<int, 3> a = {1,2,3};Sorry, wenns nicht hierher gehört, aber wie ist das denn implementiert. Sprich welche Operatoren muss man für sowas überladen?
Schau's dir an. Steht in den Headerdateien.
Würdet ihr für Bilddaten auch den std::vector nehmen?
ja
mfg.
-
bluecode schrieb:
Sorry, wenns nicht hierher gehört, aber wie ist das denn implementiert. Sprich welche Operatoren muss man für sowas überladen?
keine
Das ist ein alter Trickstruct B { int a, b, c; }; struct X { B b1; int i; B b2[2]; }; int main() { B b = { 1, //a 2, //b 3 //c }; X x = { {1, 2, 3}, //b1 4, //i {{5, 6, 7}, {8, 9, 10}} //b2 }; x; }
-
das geht, weil boost::array ein aggregat ist. dafür muss es auf einen selbstdefinierten konstruktor und destruktor verzichten, was dazu führt, dass boost::array nur fast ein container im sinne der standard bibliothek ist.
-
Übertreibe ich jetzt oder bin ich rückständig?
Wieso zum Teufel nehmt ihr für Arrays std::vector oder boost::array. Bald kommt bestimmt boost::bool.
Ich finde normale Arrays da einfach praktischer.
-
_42 schrieb:
Wieso zum Teufel nehmt ihr für Arrays std::vector oder boost::array. Bald kommt bestimmt boost::bool.
Haha, sehr gut

Nimm für Bilddaten bitte normale arrays!! Da kannst du dann auch einfach mit read binary Daten reinlesen!
m_image = new char[dim_x*dim_y]; FileBin.read(m_image , FileSize); FileBin.close();Grüße vom boost:void*
-
Bald kommt bestimmt boost::bool.
Wieso kommt noch? Gibts doch schon!

http://www.boost.org/doc/html/tribool.html
:p
-
Gast25250 schrieb:
_42 schrieb:
Wieso zum Teufel nehmt ihr für Arrays std::vector oder boost::array. Bald kommt bestimmt boost::bool.
Haha, sehr gut

Nimm für Bilddaten bitte normale arrays!! Da kannst du dann auch einfach mit read binary Daten reinlesen!
m_image = new char[dim_x*dim_y]; FileBin.read(m_image , FileSize); FileBin.close();Grüße vom boost:void*
Nix da
Das geht auch mit std::vector:#include <iostream> #include <fstream> #include <vector> #include <cassert> int main() { std::vector<char> image; std::ifstream file("asd.bmp", std::ios::ate | std::ios::binary); assert(file); unsigned int filesize = file.tellg(); file.seekg(0); // ... image.reserve(filesize); file.read(&image[0], filesize); // ... std::ofstream fout("copy.bmp", std::ios::binary); assert(file); fout.write(&image[0], filesize); }Und hierbei lässt sich nicht so leicht ein delete[] vergessen.
mfg.
-
Hab vor ein paar Tagen einen einfachen Laufzeittest mit array vs. vector gemacht (eben wegen Bilddaten).
Probiert das mal bitte aus und sagt mir, welcher Zeitunterschied bei euch rauskommt. Bei mir war das Array um den Faktor 30(!) schneller.
Deswegen hab ich mich erstmal für das Array entschieden.
Aber vielleicht hab ich ja auch falsch gemessen...#include <iostream> #include <vector> #include <windows.h> using namespace std; void arr(int size) { int* myArray = new int[size]; for(int i=0; i<size; i++) myArray[i] = 1; for(int j=0; j<size; j++) myArray[j] *= 3; delete[] myArray; } void vec(int size) { vector<int>* myVector = new vector<int>; for(int i=0; i<size; i++) myVector->push_back(i); for(int j=0; j<size; j++) (*myVector)[j] *= 3; delete myVector; } void wait() { cin.clear(); cin.ignore(cin.rdbuf()->in_avail()); cin.get(); } int main(void) { double start = 0, end = 0; double arrayZeiten[10]; double vectorZeiten[10]; for(int i=0; i<10; i++) { start = GetTickCount(); arr(300000); end = GetTickCount(); arrayZeiten[i] = end - start; start = GetTickCount(); vec(300000); end = GetTickCount(); vectorZeiten[i] = end - start; } double arrayD = 0, vectorD = 0; for(i=0; i<10; i++) arrayD += arrayZeiten[i]; cout << "Array-Zeiten: " << arrayD / 10 << endl; for(i=0; i<10; i++) vectorD += vectorZeiten[i]; cout << "Vector-Zeiten: " << vectorD / 10 << endl; wait(); return 0; }Würd mich mal interessieren, was bei euch für Werte rauskommen.
-
Du machst mir Spaß, das Array initalisierst du gleich mit der richtigen Größe und den std::vector nicht, schon klar dass der langsamer ist, der muss ja ständig neuen Speicher herscheffeln. Gib dem vector die Größe gleich im Ctor mit.
Im Übrigen ist es nicht notwendig, den vector selber auf dem Heap anzulegen.
-
DarthZiu schrieb:
for(int i=0; i<size; i++)
myArray[i] = 1;for(int i=0; i<size; i++)
myVector->push_back(i);Ist aber nicht wirklich das gleiche und push_back wird immer langsamer sein als [i].
-
DarthZiu! Du vergleichst einen statischen "Container" mit einem dynamischen Container. Ehm, das passt doch irgendwie nicht. Denn das Array kann in der Form einfach nicht das leisten, was vector leisten kann. Wenn dann müsstest du mit Array die gleich Funktionalität nachbilden: bei jeder Index-Erhöhung das selbst Array resizen. Mal schauen wie schnell du dann bist.
Der Vector spielt dann seinen Vorteil aus, wenn dir beim Anlegen des Containers die Endgröße unbekannt ist. Da kannst du noch soviele Performancetests machen, da wird jeder vector (wenn er vernünftig implementiert ist) sehr gute Arbeit leisten.
Ansonst kann man auch mit reserve()-Methode nach der Vector-Konstruktion die Laufzeit für das push_back drastisch runter drücken. Dann reserviert der Vector schon mal Speicher vor und du kannst trotzdem mit push_back arbeiten, weil die size() dann unabhängig vom reserve() arbeitet. Bei GPC-Vorschlag wäre size() allerdings gleich zu Anfang >0. Dann würde man anstatt push_back() den []-Op oder at() benutzen (wobei at() sicherer gg. Bufferoverflows ist, aber etwas langsamer, ggü. dem unsicheren []-Op).
Man muß einfach nur wissen, wie man vector benutzt, dann arbeitet dieser optimal und sicherer als jedes rohe Array.
-
void vec(int size) { vector<int>* myVector = new vector<int>(size); for(int i=0; i<size; i++) (*myVector)[i] = i; for(int j=0; j<size; j++) (*myVector)[j] *= 3; delete myVector; }Ist das jetzt richtig (effektiv)? Immer noch Faktor 10 langsamer als das Array.
-
Artchi schrieb:
Man muß einfach nur wissen, wie man vector benutzt, dann arbeitet dieser optimal und sicherer als jedes rohe Array.
Dass ein vector sicherer und komfortabler als ein array ist, ist mir klar. Ich benutze vectoren auch so oft wie möglich.
Mein Problem ist aber, dass ich eine ziemliche Datenmenge (bis zu 20 Bilder pro Sekunde - in einer Auflösung von mindestens 640x480 (307200 Byte-Werte)) erfassen und verarbeiten muss.
Hier wollte ich ebenfalls vector benutzen und habe deswegen diesen "Performance-Test" gemacht. Aber einen Zeitaufwand, der 5 bis 10 mal höher ist, kann ich mir an dieser Stelle einfach nicht leisten.
Das ist der Grund meines ersten Posts.PS: Vielleicht drücken wir den Zeitaufwand mit weiteren Verbesserungsvorschlägen ja noch auf einen annehmbaren Wert.

-
Schon mal versucht das std::vector-Objekt auf dem Stack statt auf dem Heap anzulegen? Dadurch, daß du über einen Zeiger auf dein Objekt zugreifst, hast du eine zusätzliche Indirektion, die Zeit kostet. Kann allerdings auch sein, daß das wegoptimiert wird (dazu wäre es interessant zu wissen mit welchen Optimierungs-Optionen du kompilierst).
-
So, hier mal mein Test:
Ich habe deinen ersten Code so übernommen. Habe die Größe des Übergabe-Params von 300.000 auf 10.000.000 erhöht, weil bei deinen Werten mein Compilat nur 2x so langsam war und nicht 30x.
Mit den 10.000.000x10 Durchläufen hat sich das auf 4x verlangsamt.Zeit: 4 Sekunden für den Vector und 1 Sekunden für das Array.
So, das war jetzt OHNE Reservierung!!!Compiler: VC++ Toolkit 2003 Professional, Compiler-Optionen: cl.exe /EHsc /G7 /O2 /Og
Vielleicht ist einfach dein Compiler und deine Std-Lib schlecht.
30x ist völlig utopisch bei 300.000 Elementen!So, meine Änderung am Code:
Ich habe einfach mal 10.000.000 Elemente im Vector reserviert, Push_back() verwendet und den Vector nicht mit new angelegt sondern auf dem Stack.Ergebnis: sowohl Array als auch Vector brauchen 1 Sekunde!!!!!!!
EDIT: hier noch mal der geänderte Code:
#include <iostream> #include <vector> #include <ctime> using namespace std; void arr(int size) { int* myArray = new int[size]; for(int i=0; i<size; i++) myArray[i] = 1; for(int j=0; j<size; j++) myArray[j] *= 3; delete[] myArray; } void vec(int size) { vector<int> myVector; myVector.reserve(size); for(int i=0; i<size; i++) myVector.push_back(i); for(int j=0; j<size; j++) myVector[j] *= 3; } void wait() { cin.clear(); cin.ignore(cin.rdbuf()->in_avail()); cin.get(); } int main(void) { time_t t = time(NULL); for(int i=0; i<10; i++) { arr(10000000); } cout << "Array duration: " << (time(NULL) - t) << endl; t = time(NULL); for(int i=0; i<10; i++) { vec(10000000); } cout << "Vector duration: " << (time(NULL) - t) << endl; wait(); return 0; }
-
Artchi schrieb:
Ergebnis: sowohl Array als auch Vector brauchen 1 Sekunde!!!!!!!
klar, es nimmt sich nicht viel. am interessantesten ist ja, dass man die richtige datenstruktur waehlt, die hier eben array ist... wie man dieses array jetzt implementiert ist bei der hoch optimierten standard library von c++ ja schon fast egal.
es ist aber gut zu wissen dass vector immer new aufruft. den speicher also dynamisch allokiert. denn wenn man mal ganz viele kleine vectoren hat, dann _kann_ es mal ins gewicht fallen. wenn wir aber von 1 vector reden, dann ist das einfach nur egal...
-
push_back() schaut doch immer nach, ob die Größe ausreicht, er kann ja nicht wissen, dass sie reichen muss. Dann muss es doch etwas langsamer sein, als der [] Zugriff, oder?
-
Shade Of Mine schrieb:
es ist aber gut zu wissen dass vector immer new aufruft. den speicher also dynamisch allokiert. denn wenn man mal ganz viele kleine vectoren hat, dann _kann_ es mal ins gewicht fallen. wenn wir aber von 1 vector reden, dann ist das einfach nur egal...
Und? Würdest du nicht viele kleine Vector haben, hättest du viele Arrays die du mit new instanzieren müsstest? Würde es Laufzeitmäßig anders sein? Sicherlich nicht...
-
FrageBehauptung schrieb:
push_back() schaut doch immer nach, ob die Größe ausreicht, er kann ja nicht wissen, dass sie reichen muss. Dann muss es doch etwas langsamer sein, als der [] Zugriff, oder?
Ja, natürlich. Aber soll ich jetzt 1 Mrd. Elemenete puschen, damit man sieht, es dauert 2 sek.? Wenn überhaupt! Leider habe ich hier auf meinem Java-Entwickler-PC kein PlatformSDK, um die Windows-Timefunktion zu nutzen. Kann hier nur Angaben in vollen Sekunden machen.
Wer will und ne genauere Zeitmessung machen kann, kann ja ausschliesslich den []-Operator benutzen. Aber das sind schon Containergrößen, die seltener vorkommen. Ich denke, man kann sagen, das Vector nicht so schlecht ist, wie zuerst der Eindruck war. Das C++-Standardkomitee hat sich auf jeden Fall seine Gedanken gemacht.