Effizienz Array versus Vector



  • Hallo,

    ich habe ein kleines Problem bzgl. der Effizienz von Vectoren aus der STL:
    Ich habe eine Klasse, die mir eine Menge von 2D Punkten kapseln soll. Dazu habe ich mir einen Datentyp
    struct point2D { int x; int y; };
    definiert.
    Die Klasse habe ich in zwei Varianten definiert: einmal die Menge von 2D Punkten als Array und einmal als Vector
    Im Konstructor mache ich folgendes:
    PointClass::PointClass (point2D point, int size)
    :vector(size) // Vector-Variante
    {

    //vector = new point2D[size]; // Array Variante
    ...
    //Zuweisungen von vector und Point

    }
    Im Destructor der Array-Variante gebe ich das Array noch per delete[] frei.
    Wenn ich etwa 60000 Objekte in einer Schleife erzeuge, ist die Array Variante um den Factor 6-7 schneller!!!
    Ich dachte Vector wäre in der STL effizient realisiert. Mache ich hier etwas falsch? Oder sollte man doch hier Arrays verwenden? Warum ist das Ganze so viel schneller?



  • Larissa schrieb:

    Wenn ich etwa 60000 Objekte in einer Schleife erzeuge, ist die Array Variante um den Factor 6-7 schneller!!!

    zeig mal die Schleife, vielleicht hast du da nen Fehler drinnen...

    Ich dachte Vector wäre in der STL effizient realisiert. Mache ich hier etwas falsch? Oder sollte man doch hier Arrays verwenden? Warum ist das Ganze so viel schneller?

    oh, es ist verdammt effizient. siehe zB in Rund Um die Programmierung den Thread 'Array'

    Wenn du aber die größe Kennst, ist es wahrscheinlich besser direkt ein Array zu nehmen (am besten noch Kapseln). Denn vector ist für dynamische Arrays sehr gut, allerdings rentiert er sich bei fixen größen nicht wirklich...

    aber ein Faktor 6 sollte da nicht dazwischen liegen...



  • point2D point;
    for (int i=0; i <800; i++)
    {
    for (int j=0; j<800; j++)
    {
    point.x=i;
    point.y=j;
    VectorClass n(point,8);
    }
    }

    die Grösse ist fix, es treten eigentlich nur zwei verschiedene Grössen auf. das wird im Konstructor behandelt



  • habe grad mal den Debug Modus abgeschaltet. wusste bisher nicht, das es sowas gibt. jetzt ist die Laufzeit identisch. Kann man da irgendwo was nachlesen, wie, warum das so ist?



  • Das hängt sicher mit verschiedenen Asserts zusammen, die in std::vector eingebaut sind.



  • Optimizer schrieb:

    Das hängt sicher mit verschiedenen Asserts zusammen, die in std::vector eingebaut sind.

    weiter kann vector::iterator in der Debug Version auch recht schön eine Klasse sein - das kann beim debuggen sinn machen 🙂

    weiters wird bei der debug version wahrscheinlich nix geinlinet, etc.

    die vector klasse hat nunmal mehr code als ein simples array braucht 🙂



  • jetzt hab ich doch noch mal ne Frage: Ist es möglich ein bedingtes Makefile anzulegen, und über den make Befehl eine Option zu übergeben, so dass der Sourcecode mal im DEBUG Modus compiliert wird und sonst optimiert?
    Vielen Dank!



  • Hat std::vector eigentlich eine Indexprüfung? Wenn nicht, in welcher Lib gibt es ein Array mit Indexprüfung? In boost-array scheinbar auch nicht.

    EDIT:

    Irrtum, boost hat doch eine Indexprüfung, bei der Methode at().



  • vector hat auch at und wirft afair out_of_range.



  • Jo.



  • Naja, aber wer benutzt schon at? Man müsste die Indexprüfung global ein und ausschalten können.



  • Ich finds ehrlich gesagt auch nicht besonders schön. Vor allem hätte man die Prüfung beim operator[] mit assert machen können, dann fällt die Belastung im Release-Build weg. Und bei at() kann man ja ganz "korrekt" mit Exceptions arbeiten.
    Kann mir mal btw. einer kurz erklären wie das mit Objekten abläuft? Wird da der Standardkonstruktor aufgerufen bei einem Pinguin-Array?

    EDIT: Anscheinend ruft std::vector bei Klassentypen den Standardkonstruktor auf und bei primitiven Typen setzt es den Wert auf 0. Ist meine Beobachtung richtig?



  • vector macht immer T(). bei int() hat das den effekt von =0.



  • Optimizer schrieb:

    EDIT: Anscheinend ruft std::vector bei Klassentypen den Standardkonstruktor auf und bei primitiven Typen setzt es den Wert auf 0. Ist meine Beobachtung richtig?

    Nein. Nur die Methode resize ruft zum Popularisieren den Standardctor des Typs auf.


Log in to reply