Einlesen einer Datei: Geschwindigkeitsoptimierung



  • Hi Community!

    Ich möchte gerne eine Datei einlesen. Bisher habe ich das so realisiert:

    string read_file(const string &path)
    {
        string buf;
        string rtrn = "";
        ifstream ifs;
    
        ifs.open(path.c_str(), ios::in);
        if(ifs.fail())
            return "";
    
        while(!ifs.eof())
        {
            getline(ifs, buf);
            rtrn = rtrn + buf + "\r\n";
        }
        rtrn = rtrn.substr(0, rtrn.length() - 2);
        return rtrn;
    }
    

    Wenn ich damit allerdings eine Datei einlese, die 300 kB groß ist, dauert das schon 10-20 Sekunden. Dass kann doch nicht sein, dass es so lange dauert, um eine einfache Textdatei einzulesen. Wenn ich die im einem Texteditor betrachte, ist die Datei ja auch sofort da.

    Liegt das vielleicht an dem Befehl getline? Braucht der so lange?

    Nach Möglichkeit möchte ich allerdings einen Zeilenumbruch mit \r\n erzwingen (ist aber nicht soooo wichtig!).

    Also: Wie geht es schneller?

    CU & Thx im Voraus
    Konstantin



  • Schon gelesen?
    Wenn es um Geschwindigkeit geht sollte man versuchen soviel wie möglich auf
    einmal zu lesen.

    Thread zu Geschwindigkeit
    Noch einer
    Und was zu EOF
    [Edit]Warum werden beim Editieren die Links weg gemacht ?

    [ Dieser Beitrag wurde am 17.06.2003 um 19:11 Uhr von C Newbie editiert. ]



  • Thx!

    Ich werd's mir mal anschauen!

    CU
    Konstantin



  • teste doch erstmal ein lockeres
    rtrn += buf;
    rtrn += "\r\n";
    statt des
    rtrn = rtrn + buf + "\r\n";

    wie viel bring das?



  • Hallo,
    und falls du den VC 6 benutzt solltest du sicherstellen, dass du vor der Benutzung der neuen fstreams deine STL gefixed hast.



  • @volkard: Meinst du, der Unterschied macht so viel aus? Na ja, ich werds mal testen.

    @HumeSikkins: Ich benutzte natürlich Borland.

    Ich glaube der Beitrag komplette datei einlesen hilft mir da schon ganz gut weiter... Das hört sich ganz gut an!

    Thx für die Antworten!

    Konstantin

    [ Dieser Beitrag wurde am 18.06.2003 um 08:30 Uhr von Konstantin editiert. ]



  • Original erstellt von Konstantin:
    @volkard: Meinst du, der Unterschied macht so viel aus? Na ja, ich werds mal testen.
    [ Dieser Beitrag wurde am 18.06.2003 um 08:30 Uhr von [qb]Konstantin
    editiert. ][/QB]

    Bin zwar nicht Volkard, werde es aber trotzdem versuchen.

    rtrn = rtrn + buf + "\r\n";
    /*Hier werden min 2 Temporäre Variablen erstellt und wieder zerstört*/
    
    rtrn += buf;
    rtrn += "\r\n";
    /*Hier wird keine Temporäre Variable benötigt*/
    

    Darum ist +=, -=, %=, /= u.s.w. immer a = a + x vorzuziehen.

    Wenn etwas falsche ist sagt es nur, bin für Wissen immer offen.



  • Original erstellt von <C Newbie>:
    Wenn etwas falsche ist sagt es nur, bin für Wissen immer offen.

    das 'e' da. (SCNR)



  • Original erstellt von <C Newbie>:
    **Bin zwar nicht Volkard, werde es aber trotzdem versuchen.

    rtrn = rtrn + buf + "\r\n";
    /*Hier werden min 2 Temporäre Variablen erstellt und wieder zerstört*/
    
    rtrn += buf;
    rtrn += "\r\n";
    /*Hier wird keine Temporäre Variable benötigt*/
    

    Darum ist +=, -=, %=, /= u.s.w. immer a = a + x vorzuziehen.

    Wenn etwas falsche ist sagt es nur, bin für Wissen immer offen.**

    Genau das sagt ja volkard...

    Devil



  • Original erstellt von HumeSikkins:
    Hallo,
    und falls du den VC 6 benutzt solltest du sicherstellen, dass du vor der Benutzung der neuen fstreams deine STL gefixed hast.

    Hm, könntest du mir darüber nen link geben ?
    Was meinst du ?

    Devil





  • @devil81 Volkard hat gesagt was er ändern könnte, ich wollte mit dem Post sagen
    warum das schneller ist, auch wenn nicht danach gefragt wurde.



  • Original erstellt von <C Newbie>:
    **Bin zwar nicht Volkard, werde es aber trotzdem versuchen.

    rtrn = rtrn + buf + "\r\n";
    /*Hier werden min 2 Temporäre Variablen erstellt und wieder zerstört*/
    
    rtrn += buf;
    rtrn += "\r\n";
    /*Hier wird keine Temporäre Variable benötigt*/
    

    Darum ist +=, -=, %=, /= u.s.w. immer a = a + x vorzuziehen.

    Wenn etwas falsche ist sagt es nur, bin für Wissen immer offen.**

    Ok, sowas dachte ich mir schon. Ich glaube aber, dass am meißten Zeit beim einlesen an sich verloren geht.

    CU & Thx
    Konstantin



  • Original erstellt von Konstantin:
    Ich glaube aber, dass am meißten Zeit beim einlesen an sich verloren geht.

    glaube ich eher nicht, denn getline geht halt nich schneller - es sei denn du nimmst OS interne Funktionen und mapst die ganze Datei in den speicher...

    dein momentanes problem ist, dass du zuviele temporaere objekte erstellst, in denen immer die ganze bisher gelesene datei hin und her kopiert werden muss.

    eleminiere diese temporaeren objekte und du wirst merklich schneller sein.



  • Nimmt so etwas wirklich soooo viel Zeit in Anspruch??? Das hätt ich ja nicht gedacht! Das gibt mir ja echt zu denken...

    Na gut, dann werde ich mal ein bisschen herumexpereimetieren, wie es am schnellsten geht.

    Danke an alle

    Konstantin



  • Das Problem liegt bei dir nicht beim einlesen der Datei.
    Bei mir dauert es ca. 0.05 sec. um eine 300 kb Datei in einen string einzulesen.
    Wie verarbeitest du den string weiter ?
    Vielleicht ist da etwas nicht optimal.



  • Original erstellt von Konstantin:
    **Nimmt so etwas wirklich soooo viel Zeit in Anspruch??? Das hätt ich ja nicht gedacht! Das gibt mir ja echt zu denken...
    **

    beispiel hier:
    rtrn = rtrn + buf + "\r\n";

    in rtrn stehen sagen wir 100KB
    dann werden

    rtrn = rtrn + buf + "\r\n";
                ^
    

    diese 100KB hier einmal kopiert und den inhalt von buf kommt auch noch rein.

    rtrn = rtrn + buf + "\r\n";
                      ^
    

    hier wird das ganze dann nochmal gemacht - 100KB kopiert und "\r\n" drangehaengt...

    das ganze wird dann rtrn zugewiesen, also wird nochmal alles kopiert.

    oder zB hier:
    rtrn = rtrn.substr(0, rtrn.length() - 2);

    es wird ein substr gebildet - in dem quasi die ganzen 300KB kopiert werden, und dieser wird dann wieder in rtrn kopiert - und dieser wird by value zurueck gegeben, also nochmal kopiert.

    wie du siehst wird bei dir _sehr_ viel kopiert. vorallem wenn der string lang wird, zB 300KB oder mehr - denn es wird dann ja immer alles kopiert (exponentiell)

    dagegen ist volkards version ideal - da wird nur das noetigste kopiert und nie der ganze string (es wird immer nur hinten angehaengt)



  • @ Shade Of Mine:
    Ok, das leuchtet mir ein. Ich habe das vorher nie so gesehen. Ich dachte immer der Operator += ist nur für schreibfaule ;-). Das der wirklich was anderes macht, hätte ich nicht gedacht.

    @ Stefan:
    Bisher lasse ich den eigentlich nur in einem Edit-Feld anzeigen.

    CU
    Konstantin



  • Original erstellt von Shade Of Mine:
    wie du siehst wird bei dir _sehr_ viel kopiert. vorallem wenn der string lang wird, zB 300KB oder mehr - denn es wird dann ja immer alles kopiert (exponentiell)

    warnung: beindruckendes fachwort erwürfelt. kunde muss neu bewertet werden.



  • Original erstellt von volkard:
    warnung: beindruckendes fachwort erwürfelt. kunde muss neu bewertet werden.

    hab ich was falsches geschrieben?

    wenn ja, dann bitte aufklären und mich nicht so verwirren...


Anmelden zum Antworten