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!