Seite 1 von 2

(Wert & 1) zu komplex oder Grundlagenwissen?

Verfasst: Di Feb 28, 2012 11:19 am
von Panke
Edit by Xin: Aus Thema Anfänger Problem if(wert & 1)...Verständnisfrage abgetrennt.


Meiner Meinung nach, ist die Verwendung des binären Und-Operators an der Stelle ganz
schlechter Stil, weil schlechter lesbar. Ferner ist
Xin hat geschrieben: Die Abfrage Wert & 1 ist weniger aufwendig als Wert % 2, ihr Ergebnis ist aber das gleiche.
zumindestens bei -O2 im gcc schlicht falsch. Der Assemblertext ist sogar identisch.

Re: Anfänger Problem if(wert & 1)...Verständnisfrage

Verfasst: Di Feb 28, 2012 11:53 am
von fat-lobyte
Panke hat geschrieben:Meiner Meinung nach, ist die Verwendung des binären Und-Operators an der Stelle ganz
schlechter Stil, weil schlechter lesbar. Ferner ist
Xin hat geschrieben: Die Abfrage Wert & 1 ist weniger aufwendig als Wert % 2, ihr Ergebnis ist aber das gleiche.
zumindestens bei -O2 im gcc schlicht falsch. Der Assemblertext ist sogar identisch.
+1

Zu frühe Optimierung verwirrt Programmierer, erzeugt Fehler und macht Dinge nur unnötig Kompliziert.
Reihenfolge:
Denken,
Schreiben,
! Messen !,
Optimieren

und nicht
Schreiben
Optimieren
Denken
Optimieren
...

Re: Anfänger Problem if(wert & 1)...Verständnisfrage

Verfasst: Di Feb 28, 2012 11:56 am
von Xin
Panke hat geschrieben:Meiner Meinung nach, ist die Verwendung des binären Und-Operators an der Stelle ganz
schlechter Stil, weil schlechter lesbar.
Es gibt eine regelmäßig wiederkehrende Diskussion darüber, was schlecht lesbar ist und was gut lesbar ist.
Manche Dinge sind jedoch wie Floskeln. Wenn Du hörst 'It's raining cats and dogs', dann regnet es nicht Katzen und Hunde, selbst wenn ich das im Deutschen vor einigen Tagen auch schon hören musste, sondern es schüttet wie aus Eimern.
Wer der Sprache Englisch mächtig ist, erwartet also keinen Niederschlag von Haustieren.

Ich gehöre zu den Leuten, die der Meinung sind, dass ob etwas gut oder schlecht ist, nicht von Leuten entschieden werden kann, die einer Sprache nicht mächtig sind. Den Trend haben wir jetzt seit 15 Jahren und das Ergebnis ist, dass Dinge, die früher einfach waren heute schlecht lesbar sind, weil man Dinge ja auch ohne irgendeinen Plan verstehen muss. "Wir werden irgendwann nicht mehr Programmieren lernen müssen, weil wir alle in UML programmieren". Den Unsinn höre ich mir jetzt auch schon 10 Jahre an.

Wenn etwas schlecht lesbar ist, wie die Floskel "Wert & 1", die aus einer Operation und zwei Operanden besteht, also genauso gut lesbar ist wie "Wert + 1", dann muss man sich fragen, was das bedeutet. Wer eine Operation mit der Komplexität "Wert + 1" als schlecht lesbar bezeichnet, hat offenbar Probleme "+" zu verstehen. Aber wir reden hier ja von "&" - entsprechend hat derjenige Probleme "&" zu verstehen. Ist also der Sprache nicht mächtig.
Diese Floskel wird immer dann verwendet, wenn es darum geht herauszufinden, ob eine Zahl ungerade ist. Das weiß man entweder, man denkt es sich, weil man "&" versteht oder man fragt nach. So entwickelt man das Verständnis für diese Floskel. So lernt man eine Programmiersprache.
Es ist nicht Ziel, die Sprache soweit zu vereinfachen, dass man irgendwann nicht mehr lesen lernen muss, weil die 26 Buchstaben so schwer voneinander zu unterscheiden sind.

Eins der größten Probleme der derzeitigen Informatik ist, dass man sie zu sehr vereinfacht hat. Es ist heutzutage schwierig Fachleute zu finden, die einen Ausdruck von der Komplexität "Wert & 1" noch problemlos verstehen können. beginner123 hat ihn jetzt verstanden... Beginner123 ist Anfänger. So kompliziert ist der Ausdruck also wohl nicht... entsprechend kompliziert ist es mit Fachleuten, die das nicht verstehen, qualitative Software herzustellen.
Panke hat geschrieben:Ferner ist
Xin hat geschrieben: Die Abfrage Wert & 1 ist weniger aufwendig als Wert % 2, ihr Ergebnis ist aber das gleiche.
zumindestens bei -O2 im gcc schlicht falsch. Der Assemblertext ist sogar identisch.
Gleiche Strategie: Verschiebung der Intelligenz in den Compiler.

Wem ich programmieren beibringe, der sollte danach in der Lage sein, eine Kompileroptimierung schreiben zu können, nicht nur sie einzuschalten. Ganz anderer Anspruch.
Wer darauf angewiesen ist, die Intelligenz auszulagern, weil ihm eine Operation zwischen einer Variablen und einer Konstanten zu komplex ist, der möge sich bitte nicht Programmierer nennen. Mit programmieren hat das jedenfalls nichts zu tun. Vielleicht reicht es, um Funktionen im Java-Framework in richtiger Reihenfolge zu rufen.

Meine Aussage steht: "Wert & 1" ist auf keinen Fall aufwendiger als "Wert % 2". Modernste Prozessoren können %2 inzwischen vielleicht auch in einem Takt rechnen - belegen dafür aber ein aufwendiges Rechenwerk. Ob das für eine Atom-CPU gilt, da würde ich meine Hand nicht für ins Feuer legen. Aber ich lege meine Hand dafür ins Feuer, dass "Wert & 1" auch mit -OInf und auch mit perfektoptimierenden Compilern nicht langsamer ist als "Wert % 2". "Wert & 1" läuft auf einer 30 Jahre alten CPU in einem Takt. Und natürlich auch auf modernen Billig-CPUs, wie der Atom, ARM, etc...

Bleibt abschließend die Frage: Zu welcher identischen Assembleranweisung wird das denn kompiliert? Zu Modulo oder zu And?

Re: Anfänger Problem if(wert & 1)...Verständnisfrage

Verfasst: Di Feb 28, 2012 12:31 pm
von fat-lobyte
Es geht nicht nur um konkret dieses Beispiel, es geht umgekehrt darum, dass Programmierer sich in Details verlieren (weil sie es ja können!), in denen sie nichts zu suchen haben. Das ist Micromanagement.

Die Aufgabe eines Programmierers ist Meinermeinung nach primär das *verhalten* eines Programms zu definieren, und nicht jedes Bit seiner Ausführung - das ist Aufgabe des Compilers.
In diesem Sinne ist übrigens auch der C und C++ Standard zu lesen, er soll ein Verhalten, ein Interface garantieren - aber nicht was genau zu jeder Zeit im Speicher steht.
Das ist übrigens die Stärke von C! Wer weiß, ob deine Anweisungen auf einer anderen CPU auch noch Schneller sind? Oder überhaupt das gleiche Ergebnis liefern?

Anscheinend glauben Leute oft, dass man für die "Performance" jedes Bit, jede Schleife, jede Operation definieren muss, weil sie denken, dass Bibliotheken (wie zum Beispiel die STL oder std::string) nur High-Level und langsam sind und man am besten sowieso alles selbst machen muss. Dabei besteht kein Interesse tatsächlich nachzumessen.

Vor allem die STL ist so geschrieben, dass es um reine Performance geht - hier werden mit Template-Zauberei Spezialfälle ebenfalls ausgenutzt.

Ich sehe es als Falsch (und eben als schlechten Stil) an, junge Programmierer erst dazu zu erziehen dass sie kompliziert, und um Ecken, und über jedes Bit nachdenken und dann erst sagt "ach ja, da gabs ja noch was, womit all das was du bis jetzt geschrieben hast obsolet wird."
Oft sind nunmal diese High-Level routinen schneller und "besser", aber in den Köpfen der Programmierer bleibt der Schmutz noch hängen.

In diesem kontext möchte ich erwähnen, dass ich es für Blödsinn halte, C++-Anfängern zu sagen, dass sie erst C lernen sollen, da es die "Grundlage" bildet. Das ist Unfug! Sie ähneln sich in der Syntax, aber wenn man C++ programmiert, dann braucht man gewisse (veraltete) Konzepte aus C nicht.

[edit] Dieser ziemlich interessante Talk von Bjarne Stroustroup (dem "Macher" von C++) beschäftigt sich mit genau diesem Thema:
http://channel9.msdn.com/Events/GoingNa ... pp11-Style

Er ist leider etwas lang, aber durchaus sehenswert.
Zu unserem Thema ist der Abschnitt: Schlechter C-Code: 12:57-17:36

Re: Anfänger Problem if(wert & 1)...Verständnisfrage

Verfasst: Di Feb 28, 2012 1:16 pm
von Panke
Was schlechter lesbar ist und was besser lesbar ist, hängt natürlich auch davon ab, wie man persönlich in der Programmierung groß geworden ist, gerade bei so kleinen Beispielen wie

Code: Alles auswählen

wert & 1 
vs.
wert % 2 == 0
.

Ich halte letzteres für wartbarer ( = besser lesbar ), weil es die Absicht hinter diesem Ausdruck besser darstellt. Das liegt nun mal daran, dass ich gelernt habe, dass eine Zahl genau dann gerade ist, wenn sie bei Teilung durch 2 keinen Rest liefert.

Gewagte These: Die Anzahl der Leute, die meine Definition mit ca. 8 Jahren gelernt haben, ist größer als die Anzahl der
Leute, die folgende Definition in der Grundschule lernten:
Eine Zahl ist genau dann gerade, wenn ihre Binärdarstellung in der kleinsten Stelle eine 0 besitzt.
Edit: Und an dieser Stelle gehört die Intelligenz meiner Meinung nach in den Übersetzer, genauso wie ich mir auch keine
Gedanken über Registernutzung machen will.

Re: Anfänger Problem if(wert & 1)...Verständnisfrage

Verfasst: Di Feb 28, 2012 1:30 pm
von Xin
fat-lobyte hat geschrieben:Die Aufgabe eines Programmierers ist Meinermeinung nach primär das *verhalten* eines Programms zu definieren, und nicht jedes Bit seiner Ausführung - das ist Aufgabe des Compilers.
Zu einer akzeptablen Ausbildung gehört, dass der Programmierer Entscheidungen treffen kann. Dafür bedarf es einem guten Verständnis, was da eigentlich passiert.
fat-lobyte hat geschrieben:In diesem Sinne ist übrigens auch der C und C++ Standard zu lesen, er soll ein Verhalten, ein Interface garantieren - aber nicht was genau zu jeder Zeit im Speicher steht.
Das ist übrigens die Stärke von C! Wer weiß, ob deine Anweisungen auf einer anderen CPU auch noch Schneller sind? Oder überhaupt das gleiche Ergebnis liefern?
Wenn wir uns nicht darauf verlassen können, dass die abstrahierte Verhalten eines Wertes auf allen Rechnern identisch ist, dann gibt es auch keine Grundlage auf der man etwas Programmieren könnte.

Die Integerdarstellung ist auf verschiedenen CPUs unterschiedlich und trotzdem ist das Ergebnis identisch. Die &-Verknüpfung ist eine klar definierte Sache und keine Frage, ob sie in Zukunft ein anderes Ergebnis liefern wird.
Das ist genauso wenig fraglich, wie die +-Verknüpfung. Wenn wir die Mathematik an den Nagel hängen - und die &-Verknüpfung ist nichts anderes als ein mathematischer Operator - dann kannst Du auch nichts zuverlässig ausrechnen.
Nichts für ungut, aber Deine Argumentation ist hier nicht an den Haaren herbeigezogen, sondern Humbug.
fat-lobyte hat geschrieben:Anscheinend glauben Leute oft, dass man für die "Performance" jedes Bit, jede Schleife, jede Operation definieren muss, weil sie denken, dass Bibliotheken (wie zum Beispiel die STL oder std::string) nur High-Level und langsam sind und man am besten sowieso alles selbst machen muss. Dabei besteht kein Interesse tatsächlich nachzumessen.
Du steigerst Dich gerade in etwas hinein. Es geht um die Anwendung eines Operators, der eindeutig definiert ist.
fat-lobyte hat geschrieben:Ich sehe es als Falsch (und eben als schlechten Stil) an, junge Programmierer erst dazu zu erziehen dass sie kompliziert, und um Ecken, und über jedes Bit nachdenken und dann erst sagt "ach ja, da gabs ja noch was, womit all das was du bis jetzt geschrieben hast obsolet wird."
Das meinst Du nun in einem anderen Zusammenhang, aber ich sage Dir ganz klar, dass ich einen Programmierer, der nie eine Liste oder ein Array (einen String) selbst verwaltet hat, keine kompliziere Datenstruktur zutraue. Was einfacheres wird man allerdings nicht finden.
Ergebnis: Ich bringe den Leuten bei, einfache Datenstrukturen zu verwalten, die dann irgendwann obsolet werden. Nicht unbedingt über die std-Lib, denn ich benutze auch eigene Arrays und eigene Strings.
Weil die Datentypen der Std-Lib mir nicht reichen.
fat-lobyte hat geschrieben:In diesem kontext möchte ich erwähnen, dass ich es für Blödsinn halte, C++-Anfängern zu sagen, dass sie erst C lernen sollen, da es die "Grundlage" bildet. Das ist Unfug! Sie ähneln sich in der Syntax, aber wenn man C++ programmiert, dann braucht man gewisse (veraltete) Konzepte aus C nicht.
Und das wären genau genommen dann welche?

Nebenher solltest Du Dir bewusst sein, dass eine Ausbildung nichts taugt, wenn man Projekte nur neu erstellen kann, aber kein vorhandenes Projekt versteht, weil man die angeblich "veralteten", aber weiterhin praktizierten Konzepte nicht versteht.

Um zu verstehen, was C++ macht, macht man es am besten mal selbst. Beim Erlernen von Konzepten geht es viel weniger darum, das Konzept zu lernen, sondern zu verstehen, warum man ein Konzept lernt.

Den Talk werde ich mir ansehen, sobald ich Zeit habe.

----------------------------
Panke hat geschrieben:Gewagte These: Die Anzahl der Leute, die meine Definition mit ca. 8 Jahren gelernt haben, ist größer als die Anzahl der Leute, die folgende Definition in der Grundschule lernten:
Eine Zahl ist genau dann gerade, wenn ihre Binärdarstellung in der kleinsten Stelle eine 0 besitzt.
Die meisten lernen in der Grundschule auch, dass wenn man einer Zahl mit 1 addiert, dass dann eine größere Zahl herauskommt. Von der These sollte man als Entwickler aber Abschied nehmen, denn ich kann Dir auch zeigen, dass i + 1 kleiner als i ist oder auch i+1 == i ist. Da hilft leider auch kein intelligenter Compiler.

Wer also Programmieren lernen will, lernt entweder programmieren oder lässt es bleiben. Wer allerdings darauf besteht, erlerntes Wissen beizubehalten und sich weigert dazuzulernen, der wird eine Menge Müll produzieren.

Informatik ist gewissermaßen "praktische Mathematik". Das lernt niemand in der Schule.

Rechne doch mal:
Ein Bauarbeiter soll ein Loch von 1m mal 1m genau 1m tief in die Erde schaufeln. Er braucht 5 Stunden. Wie lange brauchen 2 Bauarbeiter? Wie lange brauchen 5 Bauarbeiter und wie lange brauchen 25 Baubarbeiter?

Re: (Wert & 1) zu komplex oder Grundlagenwissen?

Verfasst: Di Feb 28, 2012 2:28 pm
von Panke
Es ging nur darum, welcher Fall für den Großteil der Bevölkerung offensichtlich ist,
und welcher Nachdenken bedarf.

Wenn ich zwei Möglichkeiten habe, das selbe Programm zu schreiben, wähle ich den offensichtlichen.

Es geht nicht darum, dass jemand nicht dazu lernen will. Fest steht auch, dass jeder anständige Programmierer wissen sollte, dass für ungerade Zahlen x & 1 gilt. Aber hier geht es um den Umkehrschluss.

Noch schöner wäre ja

Code: Alles auswählen

if(odd(x))
. Und jetzt komm mir nicht damit, dass der Funktionaufruf ja mit dem -Compiler anno 1978 nicht rausoptimiert wurde.

Re: (Wert & 1) zu komplex oder Grundlagenwissen?

Verfasst: Di Feb 28, 2012 2:38 pm
von Xin
Panke hat geschrieben:Noch schöner wäre ja

Code: Alles auswählen

if(odd(x))
. Und jetzt komm mir nicht damit, dass der Funktionaufruf ja mit dem -Compiler anno 1978 nicht rausoptimiert wurde.
Hehehe, ich rate Dir dazu, Cobol zu lernen.
Oder begin Pascal end.

Was ich an C besonders schön finde ist, dass sich Deklaration und Operation ohne Lesen unterscheiden lassen.
Bei Deklarationen sammelt sich Prosa an. Bei Operation häufen sich Operanten. Manche sagen, das sieht kryptisch aus.
Manche Leute finden es schön, diese optische Unterscheidbarkeit durch Prosa zu ersetzen: if odd( value ) and color.isBlue( maximum ) then begin .. end; sowas fällt quasi überhaupt nicht ins Auge und wenn man erstmal ein paar lange Quelltexte geschrieben hat, schätzt man durchaus, wenn Texte optisch eine Struktur wiedergeben: if( (value & 1) && ( color == 0x0000FF )) { .. } und so förmlich aus dem Blabla von Deklaration und Dokumentation einem entgegen kommen. Hier ist der Code, hier willst Du lesen!

Was leichter zu lesen ist? Übungssache.
Was schöner ist? Subjektiv.

Aber für die Prosa-Fans gibt es einen ausreichend großen Pool an ausgestorbenen Sprachen. Bedient euch da. ;-)
Panke hat geschrieben:Es ging nur darum, welcher Fall für den Großteil der Bevölkerung offensichtlich ist,
und welcher Nachdenken bedarf.
Der Großteil der Bevölkerung programmiert nicht.
Zum Glück. Die Frage, ob es Nachdenken bedarf, stellt sich solange nämlich nicht.
Solange gilt:
Panke hat geschrieben:Fest steht auch, dass jeder anständige Programmierer wissen sollte, dass für ungerade Zahlen x & 1 gilt.
Damit sind wir uns wohl einig, dass dieses Wissen auch im Quelltext zu finden sein darf. :-)

Re: (Wert & 1) zu komplex oder Grundlagenwissen?

Verfasst: Di Feb 28, 2012 3:18 pm
von Panke
%s/Großteil der Bevölkerung/Großteil der Programmierer/g
Damit sind wir uns wohl einig, dass dieses Wissen auch im Quelltext zu finden sein darf. :-)
Darf, falls muss. Sonst schlechtere Lösung.

Re: (Wert & 1) zu komplex oder Grundlagenwissen?

Verfasst: Di Feb 28, 2012 3:39 pm
von Xin
Panke hat geschrieben:%s/Großteil der Bevölkerung/Großteil der Programmierer/g
Der Großteil der Programmierer programmiert nicht?
Dann sind sie keine Programmierer.
Panke hat geschrieben:
Damit sind wir uns wohl einig, dass dieses Wissen auch im Quelltext zu finden sein darf. :-)
Darf, falls muss. Sonst schlechtere Lösung.
Tut mir leid. Dieses Vorgehen wird seit 15 Jahren propagiert und inzwischen gibt es ausreichend Resultate.

Es ist immer besser an eine Stelle im Code zu kommen, an der man erkennt, dass man ein Verständnisproblem hat und eine Frage formulieren kann, z.B. was ist "Wert & 1", so wie ich es propagiere und wie beginner123 gefragt hat.
Das ist ein ganz natürlicher und logischer Ablauf.
Die Alternative erfahren wir gerade in der Wirtschaft. Die Programmierer kommen an eine Stelle, wo sie Wert & 1 benötigen, aber keine Frage formulieren können, weil sie nicht wissen, wie die Funktion heißt, die sie dafür aufrufen müssen. Und selbst programmieren können sie sowas nicht, weil sie oftmals auch nicht in der Lage sind, das Problem auf dem Papier "begreifbar" zu machen.

Mein Ansatz fordert und fördert Lernbereitschaft zu einem gewissen Level. Alles so einfach wie möglich flacht die Lernkurve ab und damit auch die Erfahrungswerte, "falls muss".
Kürzlich hatten wir ja den Doktoranden, welcher mit einer indexbasierten Suchmaschine promovieren möchte. Für eine Doktor bin ich als Dipl. Inf. (FH) nicht gebildet genug, aber eine funktionierende, indexbasierte Suchmaschine habe ich letztes Jahr an einem (1.0) Samstag geschrieben.
Mir persönlich ist das inzwischen vollkommen egal. Je dümmer der Rest, desto sicherer mein Job.
Und wer von mir lernt, muss mit meinen Regeln und Ansichten klarkommen. Wer damit ein Problem hat, kann immernoch Java lernen.