objekte löschen dauert zu lange



  • Würde mich auch sehr wundern wenn da Zeit beim eigentlichen delete draufgeht.

    Ich gehe mal davon aus dass du dein Problem auch im Release-Modus beobachtet hast?

    Poste mal den Quelltext des Destruktors.

    Was ich schon des öffteren gesehen hab ist folgendes:

    ~DTor()
    {
       int time = time_now();
    
       while( ( time_now() - time ) < 200 )
       {
          warte_auf_ressource();
       }
    }
    

    Dann warten alle Objekte auf eine Ressource (z.B. ein Mutex) welche nicht freigegeben wird weil z.B. der entsprechende Thread grad arbeitet.

    Wenn das wirklich spürbar lange dauert kannst du dir auch mal die CPU-Last anschauen, wenn die auf 100 Prozent ist geht die Zeit wirklich für Arbeit und nicht fürs Warten drauf.

    Ansonsten solltest du mal über TyRoXx' Vorschlag mit dem MemoryPool nachdenken.
    Musst du riesige Felder wirklich freigeben oder kannst du den Zugriff nicht einfach kapseln sodass nach Außen kein Unterschied besteht aber du immer auf dem selben Speicher arbeitest?



  • rean schrieb:

    Was ich schon des öffteren gesehen hab ist folgendes:

    ~DTor()
    {
       int time = time_now();
    
       while( ( time_now() - time ) < 200 )
       {
          warte_auf_ressource();
       }
    }
    

    Dann warten alle Objekte auf eine Ressource (z.B. ein Mutex) welche nicht freigegeben wird

    Hier warten alle Objekte, völlig unabhängig davon, ob irgendwelche Ressourcen freigegeben sind.



  • xBlackKnightx schrieb:

    for ( unsigned int i=vector.size()-1; i > 0; --i ) {
      delete vector[i];
    }	
    vector.clear();
    

    Rückwärts mit unsigned int zählen ist gar nicht so einfach. 😉
    Hier vergisst Du das erste Element (i==0). Wenn Du aber die Schleife nach

    for ( unsigned int i=vector.size()-1; i >= 0; --i ) {
      delete vector[i];
    }
    

    abänderst, wird es eine Endlosschleife, da ein unsigned int ja nie negativ werden kann. Es müsste aber so gehen:

    for ( unsigned int i=vector.size(); i>0;) {
      --i;
      delete vector[i];
    }
    

    Gruß,
    SP



  • Verwende doch einen Iterator.



  • Sebastian Pizer schrieb:

    Rückwärts mit unsigned int zählen ist gar nicht so einfach.

    Ich glaube, daß es im vorliegenden Fall keinen Grund gibt, den Vektor von hinten nach vorne zu bearbeiten ...
    Also einfach:

    for(unsigned int i = 0; i < vector.size(); ++i)
       delete vector[i];
    


  • huch, es liegt wirklich an der for-schleife

    also der zusammenhang mit der rückwärtszählung und unsigned int?



  • TyRoXx schrieb:

    Tricks gibts da schon, aber keiner ist universell verwendbar:

    [u]3. "Zeigerlose Elemente"

    vector<IObject> m_objects;
    

    Vorteile:
    - könnte Zeit beim Löschen sparen (k. A. wieviel)

    Nachteile:
    - Zeiger auf die Elemente sind gefährlich

    die dritte Variante wollt ich nehmen aber es hat bereits zu tiefe Wurzeln und umbauen folgt mit vielen Fehlern naja.



  • huch, es liegt wirklich an der for-schleife

    Und wie kommst du darauf? Oder duerfen wir wild weiterraten ...



  • xBlackKnightx schrieb:

    huch, es liegt wirklich an der for-schleife

    also der zusammenhang mit der rückwärtszählung und unsigned int?

    Kann gut sein. Auf die Schnelle würde ich sagen, wenn Du nur ein Element im Vektor hast und dann diese Schleife beginnst, läufst Du genau in die von Sebastian Pizer aufgezeigte Falle ...
    Allerdings würde dann wohl das Programm eher abstürzen, als so lange zu laufen ...
    Wie dem auch sei, es gibt keinen (ersichtlichen) Grund, den Vektor von hinten nach vorne zu durchlaufen, und vielleicht kannst Du auch einen signed int als Schleifenzähler nehmen? Dann könntest Du bei Deiner Methode bleiben und 'i < 0' als Abbruchbedingung nehmen.



  • Sebastian Pizer schrieb:

    Rückwärts mit unsigned int zählen ist gar nicht so einfach. 😉
    Hier vergisst Du das erste Element (i==0). Wenn Du aber die Schleife nach

    for ( unsigned int i=vector.size()-1; i >= 0; --i ) {
      delete vector[i];
    }
    

    abänderst, wird es eine Endlosschleife, da ein unsigned int ja nie negativ werden kann. Es müsste aber so gehen:

    for ( unsigned int i=vector.size(); i>0;) {
      --i;
      delete vector[i];
    }
    

    Wenn's auf der Plattform einen typischen Underflow gibt
    assert( size_t(0)-1 == std::numeric_limits<size_t>::max() );
    , geht auch
    for ( size_t i=vector.size()-1; i<vector.size(); --i )
    .

    PS: Unter der Voraussetzung vector.size() < std::numeric_limits<size_t>::max()-1



  • Badestrand schrieb:

    Wenn's auf der Plattform einen typischen Underflow gibt [...]

    Das sollte für unsigned -Typen doch garantiert sein, oder?



  • Nexus schrieb:

    Badestrand schrieb:

    Wenn's auf der Plattform einen typischen Underflow gibt [...]

    Das sollte für unsigned -Typen doch garantiert sein, oder?

    Keine Ahnung, bin nicht so fit mit dem Standard 🙂 Ich schlag mal in einem neueren Draft nach..

    edit: Finde nichts dazu.


  • Administrator

    C++ Standard 14882:2003 - 3.9.1 Fundamental types - Abschnitt 4 schrieb:

    Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.

    http://en.wikipedia.org/wiki/Modular_arithmetic

    Also würde ich sagen, dass es sehr genau definiert ist, nicht? Zu Overflow steht es sogar unten explizit als Notiz. Explizit zu Underflow steht allerdings nichts, sollte aber eigentlich aus der Definition hervorgehen.

    Grüssli


Anmelden zum Antworten