Geschwindigkeit eines Algorithmus verbessern



  • Hallo ihr Cracks!

    Mit dem folgenden Algorithmus erreiche ich folgendes: Eine Datei mit Informationen welche hintereinander geschrieben wurden, lediglich duch "Komma", "Hochkomma" und/oder "Leerzeichen" voneinander getrennt, wird in eine neue Datei kopiert, jedoch ohne die o.g. Zeichen und untereinander. Also jede Information in eine neue Zeile.

    Diese Datei wiederrum wird dann mit einem anderen Algo nach relevanten Informationen gefiltert, aber das nur zur Info.

    Mir wurde (hier) geraten dies Operationen mit Streams zu realisieren, weil das schneller geht. Ok, hab ich dann auch gemacht, funktioniert auch soweit ganz gut. Nur jetzt das Problem:

    Die Datei mit den Rohdaten kann schnell mal 20-30 MB groß werden. Ist sie 1-2 MB groß tritt kein Problem auf, der Algo läuft sehr schnell "durch" und erzeugt die Ausgabedatei. Aber sobald die Rohdatendatei größer wird friert das Programm ein, oder der Algo läuft nur noch verdammt langsam, was dann dem einfrieren ziemlich nahe kommt ^^

    Ich habe schon einiges probiert, und hoffe nun, dass ihr mir weiterhelfen könnt. Woran scheitert meine Fuktion? Was mache ich falsch? Überschreite ich irgendein Größenobergrenze bei der Verwendung der Streams, oder vergesse ich vielleicht das Freigegeben irgendwelcher Daten?

    //Beginn of CharReplace
    void CharReplace(char dateiName[100])
    {
      ifstream iStream(dateiName);                    // Datei öffnen
      ofstream tempStream("CharReplace_temp.txt");    // temporäre Datei erstellen und öffnen
    
      string aktuelleZeile;
      AnsiString foobar;
      float flTmpSize;
      long curpos;
    
      Form1->StatusBar1->Panels->Items[1]->Text = "Step 1 / 2";
      Form1->StatusBar1->Panels->Items[2]->Text = "Replacing --- this may take a while";
      Application->ProcessMessages();
    
      while( getline(iStream, aktuelleZeile) )
      {
        //Komma durch Return ersetzen
        while(aktuelleZeile.find(",",0)<string::npos)
          aktuelleZeile.replace(aktuelleZeile.find(",",0),1,"\n");
    
        //Hochkommas löschen
        while(aktuelleZeile.find("'",0)<string::npos)
          aktuelleZeile.replace(aktuelleZeile.find("'",0),1,"");
    
        //Leerzeichen löschen
        while(aktuelleZeile.find(" ",0)<string::npos)
          aktuelleZeile.replace(aktuelleZeile.find(" ",0),1,"");
    
        // in tempomäre Datei schreiben
        Form1->StatusBar1->Panels->Items[1]->Text = aktuelleZeile.length();
        if (aktuelleZeile.length() != 0)
        {
          tempStream << aktuelleZeile << endl;
        }
        Form1->ProgressBar1->StepIt();
    
        //tmp filesize
        //http://www2.informatik.uni-halle.de/lehre/c/c_fopen.html
        //http://www.c-plusplus.net/forum/viewtopic-var-p-is-1450473.html#1450473
    
        flTmpSize = tempStream.tellp();
        Form1->StatusBar1->Panels->Items[4]->Text = FloatToStrF( flTmpSize/ 1024 / 1024,ffNumber,4,4) + " MB";
        Application->ProcessMessages();
      }
    
      iStream.close();
      tempStream.close();
    }
    

    Ich danke vorweg,
    Tippo

    :schland: 😉



  • streams sind zwar schon schnell, aber da du immernoch funktionsaufrufe drinhast (replace) gibt es noch eine schnellere methode:

    char *copy = new char[aktuelleZeile.size()+1];
    unsigned j = 0;
    for (unsigned i = 0; i < aktuelleZeile.size(); ++i)
    {
        if (aktuelleZeile[i] == ',')
            copy[j++] = '\n';
        else if (aktuelleZeile[i] != ' ' && aktuelleZeile[i] != '\'')
            copy[j++] = aktuelleZeile[i];
    }
    copy[j] = 0;
    tempStream << copy << endl;
    delete[] copy;
    

    Schneller dürfte es nicht mehr gehen



  • yeah, das find ich gut, daran hab ich seöber nach gar nicht gedacht einfach jedes Zeichen einzeln zu betrachten, da komme ich ohne die aufwändigen Suchfunktionen aus,

    danke!


Anmelden zum Antworten