Schneller speichern und laden



  • headmyshoulder schrieb:

    Ich werd einen Testfall schreiben und das Ergebniss hier posten. Mal sehn was rauskommt.

    Wenn es dir die Sache wert ist, immer her damit.



  • Ich wollte mal anmerken, dass ofstream ein puffernder Stream ist. Es ist also fast egal, ob man da byteweise oder in grösseren Blöcken schreibt. Der ofstream übergibt die Daten in der Regel in 8k Blöcken an das Betriebssystem.

    Und einer hat hier Locking erwähnt. Die put-Methode ist nicht thread-safe und wird nicht locken. Auch das macht nichts aus.

    Dann hat noch einer erwähnt, dass std::vector mit Sicherheit langsamer wäre, als arrays. Auch das stimmt nicht. Der Compiler sieht die komplette Implementierung des std::vector und kann daher genau die selben Optimierungen durchführen, wie mit arrays. std::vector ist ja gewissermaßen "nur" syntactic sugar (wobei ich darauf nicht verzichten will).

    Aber das Resümee hier sollte sein, dass eine Performancemessung ohne Optimierung nichts bringt.

    Ach ja - die Aussagen bezüglich ofstream gelten nicht für den xlC-Compiler. Da sind die iostreams indiskutabel langsam. Aber ich bezweifle, dass hier jemand mit dem xlC arbeitet.



  • Das ostream bufferd habe ich gewusst, ich dachte deshalb ja anfangs auch, dass das mit dem Vekto sinnlos ist. Hat ja auch nur 2 Sekunden rausgeholt...



  • tntnet schrieb:

    std::vector ist ja gewissermaßen "nur" syntactic sugar

    Naja, es ist syntactic sugar für mit new[] angelegte Arrays, was hier allerdings nicht der Fall ist.
    Von der Natur her entspricht einem multidimensionalen Array wie Block blocks[8][8][8]; grob eher ein solches Konstrukt:

    vector<Block> blocks;
        Chunk() : blocks(8*8*8) {}
        Block& getBlock(int x,int y,int z) {return blocks[x*64+y*8+z];}
    

    Und in der Tat, auch mit vector bleibt die Laufzeit bei mir weitgehend unverändert (0.20s statt 0.18s).

    @Die erinnerung
    Selbst mit deinen Klassen läuft das bei mir noch in 0.45s. Irgendwie habe ich das Gefühl, dass da immer noch nicht alles optimal läuft (es sei denn, du hast noch einen Pentium II oder ähnliches).
    Aber wenn du schon zufrieden bist, dann ist ja gut.



  • Athar schrieb:

    tntnet schrieb:

    std::vector ist ja gewissermaßen "nur" syntactic sugar

    Naja, es ist syntactic sugar für mit new[] angelegte Arrays, was hier allerdings nicht der Fall ist.

    Nö, ist er nicht.



  • Möge er sich länger fassen.


  • Mod

    Athar schrieb:

    Möge er sich länger fassen.

    vector ist syntaktischer Zucker für std::allocator<T>, welcher syntaktischer Zucker für operator new(T) ist, welcher syntaktischer Zucker für new T ist.



  • Welcher syntaktischer Zucker für malloc() und placement new ist, welches syntaktischer Zucker für Konstruktoraufruf + Cast ist? 🤡



  • hustbaer schrieb:

    headmyshoulder schrieb:

    Ich werd einen Testfall schreiben und das Ergebniss hier posten. Mal sehn was rauskommt.

    Wenn es dir die Sache wert ist, immer her damit.

    Ok, ich geb mich geschlagen. In meinen Tests waren beide Varianten gleich schnell.

    Ich hab drei Tests durchgeführt:

    • array< array< array< double , N3 > , N2 > , N1 >
    • vector< vector< vector< double > > >
    • vector< double > in einem Block, daher die Größe des Vektors ist N1*N2*N3 und die Indices werden über berechnet

    Bei allen ist es Tests ist es egal ob die Indices in der innerste komplette berechnet werden oder nur noch teilweise. Der Code ist hier zu finden:

    http://pastebin.com/DW5zEPGi
    http://pastebin.com/x6L2dkcA
    http://pastebin.com/2t1cN9U9



  • Worauf ich hinaus wollte: ein vector<vector<vector<Block> > > gleicht auf unterer Ebene eher dem da:

    Block*** blocks;
    Chunk()
    {
      blocks=new Block**[8];
      for (int i=0;i<8;i++)
      {
        blocks[i]=new Block*[8];
        for (int j=0;j<8;j++)
        {
          blocks[i][j]=new Block[8];
        }
      }
    }
    

    als dem da:

    Block  blocks[8][8][8];
    


  • Zu meinem Rechner:

    Ich kann nur sagen Schrott, Schrott und nochmals Schrott. Den kann man nicht mal mehr als Mühle bezeichnen, von daher bin ich mit 4-4,5 Sekunden vollkommen zufrieden!

    Prozessor:

    Intel Pentium 4 * 2,8 GHz und 2,5 GB RAM (Plus Grafikkarte mit 1 GB VRAM)

    Noch Fragen???



  • sollte trotzdem keine Sekunde dauern. Miss mal die reine Schreibzeit, wie schon vorher als Beispiel gebracht wurde. Wenn das weniger als die Hälfte der Laufzeit ist, dann läuft bei dir noch was falsch.



  • cooky451 schrieb:

    Welcher syntaktischer Zucker für malloc() und placement new ist, welches syntaktischer Zucker für Konstruktoraufruf + Cast ist? 🤡

    Ich würde statt malloc eher operator new(size_t) sagen, und was placement new angeht, das ist schon die einzige Möglichkeit einen Konstruktor direkt aufzurufen, kann man also wohl nicht mehr als "syntactic sugar" gelten lassen.



  • headmyshoulder schrieb:

    hustbaer schrieb:

    headmyshoulder schrieb:

    Ich werd einen Testfall schreiben und das Ergebniss hier posten. Mal sehn was rauskommt.

    Wenn es dir die Sache wert ist, immer her damit.

    Ok, ich geb mich geschlagen. In meinen Tests waren beide Varianten gleich schnell.
    (...)
    http://pastebin.com/DW5zEPGi
    http://pastebin.com/x6L2dkcA
    http://pastebin.com/2t1cN9U9

    Habs nur überflogen, sieht aber nach halbwegs gutem Test-Code aus (vonwegen unerwünschte Optimierungen verhindern und so) 👍


Anmelden zum Antworten