Wieviel LOC pro Tag?



  • Was ist mit Trennung der Worte mit anderen Whitespaces, wie Tabs? 😃 (Ansonsten ein tolles anschauliches Beispiel)



  • Citizen42 schrieb:

    Was ist mit Trennung der Worte mit anderen Whitespaces, wie Tabs? 😃

    😛

    In den Spielregeln wurde alles, was nicht Leerzeichen oder EOF ist als Wort behandelt. Das gilt auch für Satzzeichen. Z.b. "Hallo.Welt!" ist ein Wort.

    Inspiriert ist die Aufgabe durch argv, in der die komplette Kommandozeile in einzelne Abschnitte unterteilt werden muss. Eine solche Funktion wurde im Studium benötigt, um eine eigene Shell zu schreiben und es zeigte sich, dass die Aufgabe hervorragend geeignet ist, Programmieranfänger zum Denken anzuregen. 😉

    Citizen42 schrieb:

    (Ansonsten ein tolles anschauliches Beispiel)

    Der komplette Kram findet sich hier.



  • Vor einigen Jahren hatte mein Bruder ein Projekt bei der Lufthansa.
    War auf 100 oder so Mannjahre veranschlagt.

    Mein Bruder hatte schon ganz am Anfang zu seinen Chefs gesagt "das wird so nix, Konzept taugt nix". Hat keiner zugehört.
    Es ist nie was dabei rausgekommen weil das Konzept von Anfang an Quatsch war.

    Die Programmierer haben in FFM den ganzen Tag nur gespielt oder geschlafen.

    Nach einem Jahr hat mein Bruder gekündigt weil es ihm zu langweilig war (obwohl er über 6000 DM/Monat fürs Nixtun bekam).



  • Xin schrieb:

    Es geht aber auch zu kürzer - und langsamer.

    int c = 0;
    
       while ( *( str++ ))
          *str != ' ' && ( *( str-1 ) == ' '&&  c++ );
    
       return c;
    

    Es geht also auch sehr kurz. Die letzte Variante wurde mir spontan von einem Kollegen frei aus dem Kopf ohne Test diktiert. Fehlerfrei. Die letzte Variante wird vielen aber unverständlich sein. Und da sie langsamer ist, würde ich sie als schlechter beschrieben.
    Sie hat aber weniger LOC. (snip)

    Ich hab - bevor die ganze Diskussion ausgeufert ist - schon geschrieben dass der ideale Code nie der kürzeste ist, sondern "etwas länger als der kürzeste". Aber - wieder ein Erfahrungswert - von der Länge her näher am kürzesten als am Durchschnitt.

    Oder anders gesagt: ich hab schon viel schlechten langen Code gesehen, aber noch wenig schlechten kurzen Code.
    Ausgenommen schlechten kurzen Code der schlecht war weil er zu wenig gemacht hat (z.B. Corner-Cases nicht abgedeckt, keine Fehlerüberprüfungen etc.). Hauptsächlich aus dem Grund hab ich die Sache mit "gleiche Features" ins Spiel gebracht. Weil es mMn. keinen Sinn macht LOC Zahlen von Codes zu vergleichen die nicht wenigstens inetwa gleich robust sind bzw. die gleichen Fälle abdecken. Bzw. die gleichen funktionalen und nicht-funktionalen Anforderungen erfüllen (Thema "leicht änderbar mit wenig geänderten LOC" usw.).

    Also ja: der Code da oben wäre mir auch "zu kurz". Findet man erfahrungsgemäss aber wie schon gesagt viel viel seltener als zu langen Code. Ist aber natürlich fast gleich schlimm.



  • OT:

    Ich hätte spontan mal das abgeliefert:

    int words = 0;
    
    char ch;
    bool lastWasSpace = true;
    while (ch = *str++)
    {
        bool const isSpace = (ch == ' ');
        if (lastWasSpace && !isSpace)
            words++;
        lastWasSpace = isSpace;
    }
    

    Liesse sich mit ein Bisschen Getrixe vermutlich auch schnell machen.
    Man könnte z.B. lastWasSpace und isSpace zusammen in z.B. einen int packen (in Bit 0 und Bit 1) und dann words += helperArray[dieserInt]; machen.
    Aber dann wird's auch wieder unleserlich 🙂



  • Xin schrieb:

    while( *str != ' ' && *str ) ++str; // Leerzeichen überspringen

    Kommentar ist falsch und irreführend

    und jetzt kommt natürlich der Hammer um 03:18:

    int main(int argc, char* argv[])
    {
    char *line = " aaa bbb  ccc  ";
    int words = 0;
    
    	words = isWord( line );
    }
    
    int isWord( char *line )
    {
    int ret = 0;
    	while( *line && isspace( (int) *(line)++ ) );
    	if( !(*line) )
    		return( ret );
    	while( *line && !isspace( (int) *(line)++ ) );
    	ret = 1 ;
    	ret += isWord( line );
    
    return( ret );
    }
    

    EDIT:
    Klappt nur leider nicht mit line = "a", ist mir jetzt aber auch zu spät, um da noch weiter rumzuspielen.

    Keine Sorge, weiß schon, daß es daran liegt:

    if( !(*line) )
    

    Kannst du deinen Studenten mal vorlegen Xin und fragen warum es funktioniert und dann fragen, warum "a" nicht funktioniert.



  • OT

    Hm.
    Um das (Wörter Zählen) richtig schnell zu bekommen müsste man zu krummen Tricks greifen.

    z.B. gucken ob es "safe" ist mehr als ein Byte zu lesen - wenn man nicht gerade an einer Page-Boundary ist kann man sich das ja leisten. Dann könnte man z.B. mit SIMD Befehlen 8 Byte auf einmal verwursten.

    IIRC auch ein Standardtrick bei schnellen strlen() Implementierungen.



  • hustbaer schrieb:

    Ich hab - bevor die ganze Diskussion ausgeufert ist - schon geschrieben dass der ideale Code nie der kürzeste ist, sondern "etwas länger als der kürzeste". Aber - wieder ein Erfahrungswert - von der Länge her näher am kürzesten als am Durchschnitt.

    Oder anders gesagt: ich hab schon viel schlechten langen Code gesehen, aber noch wenig schlechten kurzen Code.

    Nach gutem Code kommt Code, der krampfhaft bemüht ist, kurz zu sein ohne darauf zu achten, dass er gut ist.

    Das Hauptziel ist allerdings maximale Geschwindigkeit. Es ging in erster Priorität nicht um schön zu sein, sondern um schnell.

    hustbaer schrieb:

    Liesse sich mit ein Bisschen Getrixe vermutlich auch schnell machen.
    Man könnte z.B. lastWasSpace und isSpace zusammen in z.B. einen int packen (in Bit 0 und Bit 1) und dann words += helperArray[dieserInt]; machen.
    Aber dann wird's auch wieder unleserlich 🙂

    Und sehr, sehr langsam. ^^

    EOP schrieb:

    Xin schrieb:

    while( *str != ' ' && *str ) ++str; // Leerzeichen überspringen

    Kommentar ist falsch und irreführend

    Der Kommentar ist in meinen Augen absolut in Ordnung, weil er den Algorithmus und nicht den Quelltext beschreibt. *str ist ein Implementationsdetail, keine Problemlösung.

    Edit: *stirnklatsch* 😃

    EOP schrieb:

    und jetzt kommt natürlich der Hammer um 03:18:

    int main(int argc, char* argv[])
    {
    char *line = " aaa bbb  ccc  ";
    int words = 0;
    
    	words = isWord( line );
    }
    
    int isWord( char *line )
    {
    int ret = 0;
    	while( *line && isspace( (int) *(line)++ ) );
    	if( !(*line) )
    		return( ret );
    	while( *line && !isspace( (int) *(line)++ ) );
    	ret = 1 ;
    	ret += isWord( line );
    
    return( ret );
    }
    

    EDIT:
    Klappt nur leider nicht mit line = "a", ist mir jetzt aber auch zu spät, um da noch weiter rumzuspielen.

    Dein Code ist erstens gegen unsere Spielregeln (alles außer ' ' ist ein Wort), was ihn zum einen nicht vergleichbar machen würde und wenn wir ignorieren, dass er ein anderes Ergebnis liefern wird, wird er auch noch sehr langsam sein, weil Funktionsaufrufe (isspace und Rekursion) einfach nur teuer sind.
    Warum definierst und initialisierst Du ret, nur um es zurück zu geben bzw. es zu überschreiben!? ret brauchst Du doch gar nicht!?

    Ein Funktionsname ist ebenfalls ein Kommentar. Und "isWord" beschreibt nicht, was die Funktion leisten soll. Die Variable 'line' ergibt bei 'ispsace()' auch keinen Sinn, da ein Newline als Whitesapace erkennt.

    Und da Du ja selbst schon gemerkt hast, dass es auch noch nicht funktioniert,

    EOP schrieb:

    Keine Sorge, weiß schon, daß es daran liegt:

    if( !(*line) )
    

    Kannst du deinen Studenten mal vorlegen Xin und fragen warum es funktioniert und dann fragen, warum "a" nicht funktioniert.

    Ich mache derzeit keine Schulungen und Tutorien schon lange nicht mehr.

    hustbaer schrieb:

    Hm.
    Um das (Wörter Zählen) richtig schnell zu bekommen müsste man zu krummen Tricks greifen.

    Das ist das gemeine, dass man beim Wörterzählen noch auf das Leerzeichen prüfen muss. Falls hier noch was spannendes kommt, gucke ich nochmal, ob ich die Testsuite nochmal finde. ^^

    Aber schon lustig, dass man hier so viele Leute noch mit einem scheinbar derart trivialen Problem durch die Nacht bringen kann. 😃



  • Xin schrieb:

    Aber schon lustig, dass man hier so viele Leute noch mit einem scheinbar derart trivialen Problem durch die Nacht bringen kann. 😃

    Hab zum Glück abgesachaltet, als Code von Dir kam.

    Xin schrieb:

    EOP schrieb:

    Xin schrieb:

    while( *str != ' ' && *str ) ++str; // Leerzeichen überspringen

    Kommentar ist falsch und irreführend

    Der Kommentar ist in meinen Augen absolut in Ordnung, weil er den Algorithmus und nicht den Quelltext beschreibt. *str ist ein Implementationsdetail, keine Problemlösung.

    Ich sehe auch nicht so direkt, daß der Code Leerzeichen überspringt. Hätte das Gegenteil geraten, wenn Du nocht so sicher wärst.



  • volkard schrieb:

    Xin schrieb:

    EOP schrieb:

    Xin schrieb:

    while( *str != ' ' && *str ) ++str; // Leerzeichen überspringen

    Kommentar ist falsch und irreführend

    Der Kommentar ist in meinen Augen absolut in Ordnung, weil er den Algorithmus und nicht den Quelltext beschreibt. *str ist ein Implementationsdetail, keine Problemlösung.

    Ich sehe auch nicht so direkt, daß der Code Leerzeichen überspringt. Hätte das Gegenteil geraten, wenn Du nocht so sicher wärst.

    wtf... *lach*

    Manchmal hat man echt Tomaten auf den Augen. 😃



  • Xin schrieb:

    volkard schrieb:

    Xin schrieb:

    EOP schrieb:

    Xin schrieb:

    while( *str != ' ' && *str ) ++str; // Leerzeichen überspringen

    Kommentar ist falsch und irreführend

    Der Kommentar ist in meinen Augen absolut in Ordnung, weil er den Algorithmus und nicht den Quelltext beschreibt. *str ist ein Implementationsdetail, keine Problemlösung.

    Ich sehe auch nicht so direkt, daß der Code Leerzeichen überspringt. Hätte das Gegenteil geraten, wenn Du nocht so sicher wärst.

    wtf... *lach*

    Manchmal hat man echt Tomaten auf den Augen. 😃

    Und mir fällt sowas nach 12 Bier um 3 morgens noch auf. :p

    EDIT:
    Und natürlich ein LOL @volkard.



  • Xin schrieb:

    hustbaer schrieb:

    Liesse sich mit ein Bisschen Getrixe vermutlich auch schnell machen.
    Man könnte z.B. lastWasSpace und isSpace zusammen in z.B. einen int packen (in Bit 0 und Bit 1) und dann words += helperArray[dieserInt]; machen.
    Aber dann wird's auch wieder unleserlich 🙂

    Und sehr, sehr langsam. ^^

    So wild ist das gar nicht.
    So um die 30% langsamer als deine schnelle Variante.
    Mit manuellem Loop-Unrolling (hab jetzt mal 7-fach probiert) dann auf x86 etwa gleich schnell und auf x64 etwa 20% schneller 😉

    Xin schrieb:

    hustbaer schrieb:

    Hm.
    Um das (Wörter Zählen) richtig schnell zu bekommen müsste man zu krummen Tricks greifen.

    Das ist das gemeine, dass man beim Wörterzählen noch auf das Leerzeichen prüfen muss. Falls hier noch was spannendes kommt, gucke ich nochmal, ob ich die Testsuite nochmal finde. ^^

    Schon klar das mit den Leerzeichen.
    Ich stelle mir vor:
    Byte-fürByte Loop bis Alignment auf 8 Byte passt.
    Dann 8 Byte in ein SIMD Register laden.
    Dann gucken ob eins davon ne Null ist.
    Dann vergleich mit Leerzeichen => Bitmaske draus machen.
    Bitmaske in Register stopfen und das letzte Bit der vorigen Bitmaske dazu.
    Damit nen Table-Loopup ( count += table[mask] ) => fertig. Für 8 Byte auf einmal braucht man nen Table mit 512 Einträgen. char reicht, also 512 Byte.
    So lange wiederholen wie man keine Null findet.
    Die letzten paar Byte dann wieder einzeln.
    Das sollte ohne SIMD schon ein gutes Eck schneller sein als eine "Byte für Byte" Variante. Mit SIMD, wenn alle nötigen Befehle verfügbar sind noch viel schneller. (Parallel-Vergleichen gibt's, bin nur nicht sicher ob man das Ergebnis dann auch einfach in eine Bitmaske verwandeln kann.)

    Dafür ist es halt kein portierbares C++ mehr, weil man ja offiziell nicht über die Grenzen eines Arrays bzw. einer Allokation hinauslesen darf. Sollte aber zuverlässig funktionieren, da das Alignment auf 8 Byte sicherstellt dass man zumindest keine Page angreift die man nicht hätte angreifen sollen. Und die Werte hinter der ersten Null werden auch nie wirklich ausgewertet, von daher sollte es auch Wurst sein dass man da Schrott liest oder diese Werte sogar von einer Race-Condition betroffen wären (wären, wenn man sie denn auswerten würde).



  • numLOC schrieb:

    Guten Morgen,

    ich arbeite bei einem große Mailanbieter und wir werden, unter anderem, danach bewertet wie viele Lines of Code wir pro Tag produzieren, das wird mit dem Versionskontrollsystem gemessen. Wie bei vielen Anbietern, wo die Mitarbeiter einem regen Wechsel unterzogen sind, ist der Code saumäßig schlecht und viele Köche haben da schon rumgerührt und selbst die Frameworks sind kaum updatebar, da Veränderungen daran von irgendjemanden mal vorgenommen wurden. Und für Ausbesserungen wird uns keine Zeit gegeben, da Featurausbau immer Vorrang hat.

    Ich schaffe da manchmal nur 20-50 LOC pro Tag, da alles zudem noch extrem OOP ist und man wirklich kaum eine Chance hat da den Datenfluss noch nachzuvollziehen. Es existiert eine Doku, aber die wird auch mehr stiefmütterlich behandelt.

    IBM hat auch nach KLOCs bezahlt und Steve Ballmer musste IBM klar machen, dass ein 4 KLOC Programm, das kleiner und schneller ist und das gleiche erreicht besser ist, als ein 10 KLOC oder 100 KLOC Programm:

    http://youtu.be/PWylb_5IOw0?t=38m58s

    KLOC steht für 1000 lines of Codes.


Anmelden zum Antworten