Vector größe dynamisch ändern?



  • Folgendes:

    Habe eine Klasse welche ein Vector enthält, die Elemente des Vectors kann ich entweder zum Programmstart festlegen, oder während derlaufzeit entsprechend der notwendigkeit vergrößern/verkleinern!

    Performance technisch ist ja es ja nicht unbeding von Vorteil wenn ich ein Vector städnig verkleiner und vergrößere... deswegen dachte ich ich mach in anfangst zu max. größe und verwende nur die Elemente (indexe) die ich brauche..

    Haltet ihr das für sinvoll?



  • Ich halte es für einen Vorteil des vector's (ich nehme mal an, du meinst std::vector<>), daß du die Größe nachträglich ändern kannst. Wenn du Angst hast, daß bei Größenänderungen ständig umkopiert werden muß, kannst du ja reserve() verwenden, um gleich am Anfang ausreichend Platz zu reservieren.

    (btw, langfristig nimmt die Größenänderung nicht viel Zeit in Anspruch)



  • ah danke, was macht reserve() genau? Wenn ich ein std::vecto<> mit 6 elemente anlege, und davor mit reserve(32); gemacht habe, hat der vector trozdem die größe von 6 oder?

    Gibts sowas auch bei std::map?



  • Der Vector verkleinert seinen reservierten Speicherplatz doch auch bei explizitem resize() nicht, oder? Von daher dürfte sich die tatsächliche Größe irgendwann beim Maximum einpendeln (auch wenn die tatsächlich gefüllte Größe wesentlich geringer ist).



  • reserve() fordert Speicherplatz an, ohne ihn gleich zu fertigen Elementen zu "verarbeiten" - d.h. nach einem Aufruf 'v.reserve(32);' kann der vector 32 Elemente aufnehmen, bevor er seine Kapazität vergrößern muß.
    ("Kapazität vergrößern" bedeutet dabei - er fordert einen größeren Speicherblock an und kopiert alle Elemente um)

    Eine map<> hat übrigens kein Äquivalent zu reserve() - dort wird für jedes Element ein eigener Baumknoten reserviert und in den Binärbaum eingehängt.

    @LordJaxom: Ja, macht er - die Größe schwankt zwar je nach Anforderungen, die Kapazität ("tatsächliche Größe") wächst monoton.



  • d.h.:

    std::vector<XXX> vData;
    
    vData.reserve(32);
    
    vData.resize(6);
    
    for(std::vector<XXX>::iterator it= vData.begin(); it != vData.end(); it++)
      //6 Iterationen ??
    


  • Ja, genau - vData hat eine Größe von 6 (Anzahl der Elemente) und eine Kapazität von (mindestens) 32 (reservierter Platz für Elemente).



  • super, genau das brauch ich;) Aber wie sieht der Speicherplatzbedarf aus?

    verwende einen vector welcher listen enthält.

    std::vector<std::list<DATA> > vData(6);
    
    vData.reserve(32);
    

    wenn ich jezt bspw. nur 6 elemente zu laufzeit von 32 verwende, hab ich ja rel. viel speicherplatz reserviert den ich nie brauch, oder its das nich gravierend?



  • Du hast jetzt genug Platz reserviert, um 32 (leere) list<DATA> unterzubringen (davon sind 26*sizeof(list<DATA>) Byte noch roher Speicher). Die Listen fordern für ihre Elemente nur dann Speicher an, wenn du etwas reinpackst.

    (ob diese 26*sizeof(list<DATA>) Bytes für dich kritisch sind, mußt du selber wissen - wenn du meinst, daß es zu viel ist, reservierst du beim Start etwas weniger Platz)

    PS: Wenn du zu wenig Platz reservierst, kann der vector<> damit auch leben 😉



  • ok danke, dann hab ich noch ne kleiner frage.. wenn ich ein vector als member in meiner klasse habe, kann ich die genutzte größe in der inititalisierungsliste angeben.. aber das geht wohl nich mit reserve oder=



  • BorisDieKlinge schrieb:

    wenn ich jezt bspw. nur 6 elemente zu laufzeit von 32 verwende, hab ich ja rel. viel speicherplatz reserviert den ich nie brauch, oder its das nich gravierend?

    Naja, Du hast 26 mal den Platz den eine Liste braucht "verschwendet", ob das jetzt relativ viel ist, da lässt sich drüber streiten. Denn die eigentlichen Listenelemente liegen widerum als Zeiger innerhalb der Klasse list<> (Zeiger auf erstes und Zeiger auf letztes Element).



  • BorisDieKlinge schrieb:

    ok danke, dann hab ich noch ne kleiner frage.. wenn ich ein vector als member in meiner klasse habe, kann ich die genutzte größe in der inititalisierungsliste angeben.. aber das geht wohl nich mit reserve oder=

    Nein, dem Ctor von vector<> kannst du nur eine Wunschgröße übergeben - wenn du eine Wunsch-Kapazität hast, könntest du im Klassen-Konstruktor reserve() aufrufen:

    class myclass
    {
      vector<whatever> data;
    public:
      myclass(int res_size)
      { data.reserve(res_size); }
    };
    


  • und ohne elemente hab ich da wohl da wohl einen NULL first und last zeiger!

    aber der vector wird keine listen in den 26 reservieren bereichen anlegen, erste wenn ich mit resize komme...



  • ein resize() das den vector<> verkleinert wird i.d.R. keinen Speicher freigeben, allein aus Performancegründen.

    std::vector<int> vec;
    vec.reserve(32);
    for(int i = 0; i < 10; ++i)
       vec.push_back(i);
    
    int mySize = vec.size();
    vec.resize(2);
    mySize = vec.size();
    
    int myCapacity = vec.capacity();
    


  • Falls man die Capacity wirklich verkleinern will geht das hier

    std::vector<int> vec;
    vec.reserve(32);
    for(int i = 0; i < 10; ++i)
       vec.push_back(i);
    int mySize = vec.size();
    // anstelle von vec.resize(2);
    std::vector<int>(2).swap(vec);
    mySize = vec.size();
    
    int myCapacity = vec.capacity();
    


  • Braunstein schrieb:

    Falls man die Capacity wirklich verkleinern will geht das hier

    ...
    // anstelle von vec.resize(2);
    std::vector<int>(2).swap(vec);
    ...
    

    leider nicht ganz, nun hast du einen vector<> mit zwei Elementen die jeweils mit dem Default-C'tor initialisiert sind, die alten Werte sind verloren.

    std::vector<int>(vec.begin(), vec.begin() + 2).swap(vec);
    


  • OT: Boris, planst du gerade die UberGraphicsEngine für ein Quake4X++? Ich lese von dir in letzter Zeit immer nur "was ist schneller, performanter, etc." 😉

    Grüße...

    Heiko



  • sowas in der art;) !!! Arbeite an einem Scheduler, welcher in kurzer zeit durch Trial-Error Iterationen einen optimalen Lösungsweg für Zukunftige abläufe plan..;)


Anmelden zum Antworten