Optimale Performance aus dem Proggi holen :rolleyes:



  • Servus!

    Ich habe gerade diesen Thread gelesen und bin dabei auf folgenden Code gestoßen:
    [cpp]
    #include <iostream>
    #include <fstream>

    using namespace std;

    int main(int argc, char **argv)
    {
    ifstream file("text.txt");
    char buff;
    int klein=0,gross=0,zahl=0,sonder=0;
    while(file.get(buff))
    {
    if(buff>=65 && buff<=90) gross++;
    else if(buff>=97 && buff<=122) klein++;
    else if(buff>=48 && buff<=57) zahl++;
    else sonder++;
    }
    file.close();
    cout<< "Grossbuchstaben:" << gross <<endl;
    cout<< "Kleinbuchstaben:" << klein <<endl;
    cout<< "Zahlen:" << zahl <<endl;
    cout<< "Sonderzeichen:" <<sonder;
    return 0; //das ergänze ich jetzt einfach mal, kotzt mich wirklich an, dass das fehlte! 😡
    }
    [/code]
    OK, ich als Durchschnittsoptimierer frage mich da natürlich gleich: wie liese sich dieser Code noch weiter optimieren?
    So, wie der pfiffige Codeanalytiker oder viel kontraproduktive Lesearbeit schnell und zeitsparend erkennen kann, wird hier aus einer Datei Zeichen für Zeichen eingelesen und im Programm analysiert und verarbeitet.
    Da kling3ln natürlich auch bei mir die Alarmclocken, denn Zeichen für Zeichen hört sich kontrapervormant, langwierig und langsam an!
    Deshalb meine Frage: wie optimiert man den Code am optimalsten für einen durchschnittlich modernen PC? Ich denke, die wahrscheinlichste Performancelücke wird wohl an der HDD liegen, da das Programm hauptsächlich lesearbeit verrichtet. Wäre es für die HDD nicht relaxiger, immer z.B. 10, oder mehr Zeichen einzulesen? Ich denke kaum.

    Bei einem Programm, das z.B. eine Textdatei KOPIERT!! wäre das doch was anderes, hier liegt das Problem darin, dass die HDD lesen und schreiben muss. (Schüler wissen, wie schnell man sich beim auf geschwindigkeit ausgelegten Abschreiben der Hausaufgaben einen Krampf im Schreibarm holen kann!!). Selbiges gilt hier natürlich für die HDD, denn wie wir alle Wissen, sind Festplatten das gates'sche Äquivalent zum menschlichen Hirn, auch Brainu'sepmtikus genannt. Aber egal, wie würde sich das jetzt bei so nem Kopierprogramm verhalten? Ein Zeichen Lesen, mit dem Schreibarm ne Runde durch die Datenwelt drehen, um dann das nächste einzelne Zeichen zu holen? 😮 Wohl kaum! 😡
    Wir Menschen fahren doch auch mit Bussen, da sonst die Performance auf den Straßen zusammenbricht! Damit wäre es wohl bewiesen, dass es kontraproduktiv ist, jedes Zeichen einzeln zu lesen (q.e.d.). Aber wie weit kann man gehen? Wie groß darf der Bus werden, bevor er nicht mehr um die Kurve kommt? Wie viele Zeichen darf man einlesen, bevor das Fenster zerbricht? 10? 100? 110? Man weiß es nicht. Besonders OpenSource Projekte sind gefährdet, da hier immer die Gefahr besteht, dass ein langhaariger Linux-Frickler den Quellcode auf eine 0.5 Mhz Maschine mit 2 Byte Ram portieren will. Und genau hier liegt das Problem: Allokiert der performancebewußte Softwareingenieur 10 K Speicher, qualmt die Maschine und das geschrei seitens der OpenSource aka freien Softwaregemeinde ist groß.
    Deshalb: Schreibt eure Software in Java, denn auf einer Maschine, die von der JVM nicht bezwungen wird, lassen sich auch noch 10K Speicher allokieren. Und wenn nicht, könnt ihr die Schuld auf eine Firma schieben, oder habt ihr euch noch nie gewundert, dass für C++ niemand haftbar ist? Denn mal ehrlich, es gibt wohl kaum jemanden, der die Schande C++ auf sich nehmen würde wollen. Denn es gibt genug Frickler, die in diesem Moment versuchen, die JVM auf ihr 2-Takt-Vorher-Ankurbel-Handy von vor '79 zu portieren und nur darauf warten, dass Sun einen Fehler macht!
    Und genau aus diesem Grund.... 🙄



  • Bitte den CPP-Tag reparieren und diesen Post dann löschen, thx!



  • statt byteweise lesen ist blockweise lesen besser. die blockgröße ist so ab 1024Byte gut. drunter wirds deutlich langsamer, drüber kaum noch schneller. 4k ist wohl üblich. auf 64-bittern 8k.
    außerdem das viele if aus der innersten schleife raus.
    statt

    if(buff>=65 && buff<=90) gross++; 
    else if(buff>=97 && buff<=122) klein++; 
    else if(buff>=48 && buff<=57) zahl++; 
    else sonder++;
    

    einfach nur

    ++anzahl[buff];
    

    wobei buff ein unsigned char buff ist und anzahl ein int anzahl[256] und nach dem einlesen wird dann nochmal über anzahl gelaufen und gross, klein, zahl und sonder werden gesammelt.



  • Das Programm wird gleich viel besser, wenn man es nicht Proggi nennt.



  • if(buff>=65 && buff<=90) gross++; 
    else if(buff>=97 && buff<=122) klein++; 
    else if(buff>=48 && buff<=57) zahl++; 
    else sonder++;
    

    Das kannst du durch eine Lookup Tabelle erstzen:

    if ( ascii[buff] == GROSSBUCHSTABE ) gross++;
    else if ( ascii[buff] == KLEINBUCHSTABE ) klein++;
    else if ( ascii[buff] == ZAHL ) zahl++;
    else sonder++;
    

    Obs wirklich schneller ist weiß ich nicht. volkard??



  • Leute das ist doch offensichtlich ein Troll-Posting.

    CLOSEN!



  • Headhunter schrieb:

    if(buff>=65 && buff<=90) gross++; 
    else if(buff>=97 && buff<=122) klein++; 
    else if(buff>=48 && buff<=57) zahl++; 
    else sonder++;
    

    Das kannst du durch eine Lookup Tabelle erstzen:

    if ( ascii[buff] == GROSSBUCHSTABE ) gross++;
    else if ( ascii[buff] == KLEINBUCHSTABE ) klein++;
    else if ( ascii[buff] == ZAHL ) zahl++;
    else sonder++;
    

    Obs wirklich schneller ist weiß ich nicht. volkard??

    Schneller als das Original, aber volkis ist schneller ab n (n ~ 256) Zeichen.

    Bye, TGGC (Fakten)



  • @Optimationsmaster: 😃 👍



  • volkard schrieb:

    statt byteweise lesen ist blockweise lesen besser. die blockgröße ist so ab 1024Byte gut. drunter wirds deutlich langsamer, drüber kaum noch schneller. 4k ist wohl üblich. auf 64-bittern 8k.

    Buffert ifstream nicht sowieso schon?

    Wie wäre es mit der Erweiterung von Headhunters Lösung:

    ++counters[ascii[buff]];



  • Jester schrieb:

    Buffert ifstream nicht sowieso schon?

    stimmt. also holt man nicht mehr viel raus.

    Wie wäre es mit der Erweiterung von Headhunters Lösung:
    ++counters[ascii[buff]];

    perfekt. 👍



  • könnte man auch gleich mit int-s anstatt mit einzelnen zeichen arbeiten? dann hat man natürlich nicht gleich das ergebnis, sondern verschiedene ascii-nichtascii-kombinationen gezählt, und muss diese dann entsprechend addieren...


Log in to reply