Je weniger Code desto besser?

Ein Aspekt der noch nicht genannt wurde und in der Praxis oft vernachlässigt wird, ist Code für die Fehlerbehandlung.
Dadurch wird der Code zwangsläufig länger, aber auch zuverlässiger. Es gibt nichts nervigeres als Programme die abstürzen weil auf eine Null-Referenz zugegriffen wurde oder in einen Array Out-of-Range geschrieben wurde. Ich gehe immer vom Worst-Case aus und baue viele Überprüfungen in meinen Code. Dadurch bläht sich der Code natürlich auf. Ich würde aber behaupten, dass der Code dadurch besser ist. Kommt drauf an wie man "besser" definiert.
 
  • Gefällt mir
Reaktionen: breedmaster, _killy_, madmax2010 und 3 andere
TomH22 schrieb:
Es ist seit seeligen Fortran Zeiten üblich Laufvariablen von for Schleifen i oder k zu nennen. Zumindest bei eher kurzen Schleifen finde ich dann lange, sprechende Namen wie „ArrayIndex“ unnötig, im Gegenteil, der Code wird oft sogar schwerer lesbar, weil in Summe länger.
Ja, wenn man denn ausnahmsweise mal klassische for-Schleifen benutzen muss anstatt über eine Liste zu iterieren, dann kann und ggf. sollte man die klassischen indize Bezeichner i, j, k benutzen. Es kann auch in der behandelten Domäne etablierte Bezeichner geben die man dann ggf. ebenfalls benutzen sollte anstelle von Eigenschöpfungen.
Bedacht ist denke ich unangebracht aber es gibt selbstredend Ausnahmen.
 
TomH22 schrieb:
Also z.B. if (p!=NULL) anstatt if (p).
Sowas finde ich zB absolute Unart. Also die “Kurzform”.
Wenn wirklich p is Null und p== false dasselbe sein soll… mmm. Aber wenn ich nicht ganz sauber gebaut hab und mein p wider Erwarten nicht das enthält was ich dachte, dann fliegt mir das um die Ohren.

If(p) nur, wenn p nicht null sein KANN und wenn es Boolean ist.
Hier konkret ist tatsächlich “mehr” besser als weniger.
 
  • Gefällt mir
Reaktionen: madmax2010 und BeBur
RalphS schrieb:
Hier konkret ist tatsächlich “mehr” besser als weniger.
Als Ergänzung: Syntaktische "Clevere Tricks und Kniffe" sind genau das was man vermeiden sollte. Weil den "Trick" muss man später und müssen andere dann im Kopf on the fly unnötig übersetzen, das erhöht den 'cognitive load'
 
  • Gefällt mir
Reaktionen: Skysnake und mental.dIseASe
Es gibt aber Grenzen. Man kann seinen Code natürlich so bescheuert gestalten, daß ihn noch jeder Firstie versteht... Problem daran, dann ist der Code in den allermeisten Fällen eben bescheuert.

Für sowas gibt es Dokus. Ansonsten dürfte man kein OO verwenden - da hat man fünf verschiedene .Add() Methoden die alle was anderes machen können und wenn man draufguckt, weiß man "okay hinzufügen" aber eben auch nicht mehr.

Zuallererstmal gibts die Arbeitsfähigkeit des Codes. Erst danach alles andere. Und wenn ich in eine Schleife jeden Befehl auf der Kommandozeile ausgeben lasse, dann ist das schön für den Firstie, aber es verzögert meine Laufzeit um ein Vielfaches.
=> Da hat der Firstie halt Pech.
 
  • Gefällt mir
Reaktionen: Quonux
BeBur schrieb:
Ja, wenn man denn ausnahmsweise mal klassische for-Schleifen benutzen muss anstatt über eine Liste zu iterieren, dann kann und ggf. sollte man die klassischen indize Bezeichner i, j, k benutzen.
Wenn man low-level Code in C schreibt (z.B. hardwarenah für Mikrocontroller) sind for Schleifen noch ein sehr häufiges Konstrukt. Außerdem hatte ich die for Schleife als generelles Beispiel für „idiomatischen“ Code gewählt. Bei List-Iteratoren hat man auch eine Variable für das aktuelle Element, die nenne ich meistens „e“.

BeBur schrieb:
Syntaktische "Clevere Tricks und Kniffe" sind genau das was man vermeiden sollte.
Wenn es “gebräuchliche“ Kniffe sind, die typisch für eine bestimmte Sprache/Umgebung/Framework sind, sind sie ok.
Beispiel Lua: Die Sprache hat keinen tenary Operator (das ? in Curly-Braces Sprachen), stattdessen schreibt man <cond expr> and <then expr> or <else expr>
Durch die short-circuit Evaluierung funktioniert das. Wenn man öfter Lua programmiert, kennt man das Muster. Es hat aber auch seine Tücken (wenn then expr false ist wird auch der else-expr ausgeführt), daher ist es ein zweischneidiges Schwert. Ich mag es daher nicht besonders, aber nutze es trotzdem öfter.

RalphS schrieb:
Zuallererstmal gibts die Arbeitsfähigkeit des Codes. Erst danach alles andere
Hmm. Wartbarkeit (und dazu gehört auch Lesbarkeit) ist für mich auf einer Stufe mit Korrektheit und Performance. Bei uns sind Code-Reviews Pflicht. Code den der Reviewer nicht versteht, ist für den Autor viel Arbeit durch Rückfragen…
 
  • Gefällt mir
Reaktionen: mental.dIseASe
TomH22 schrieb:
Wenn es “gebräuchliche“ Kniffe sind, die typisch für eine bestimmte Sprache/Umgebung/Framework sind, sind sie ok.
Ja, das ist das was der Begriff 'idiomatisch' bezeichnet.

TomH22 schrieb:
Wenn man low-level Code in C schreibt (z.B. hardwarenah für Mikrocontroller) sind for Schleifen noch ein sehr häufiges Konstrukt. Außerdem hatte ich die for Schleife als generelles Beispiel für „idiomatischen“ Code gewählt. Bei List-Iteratoren hat man auch eine Variable für das aktuelle Element, die nenne ich meistens „e“.
Ja, hardwarenah und in anderen Bereichen sind for-Schleifen noch sehr üblich. Wenn man über eine Liste iteriert, dann sollte aber ein treffender Bezeichner gewählt werden und nicht einfach nur "e". Siehe mein Ruby Beispiel weiter oben.
 
Grundsätzlich "Ja" mit Sternchen.

Grimba schrieb:
Je weniger komplex deine Lösung ist, desto besser im Sinne von so wenig komplex wie möglich, aber so komplex wie nötig.
Occam's razor: eine einfachere Erklärung ist wahrscheinlich die bessere.

Kleine Programme können einfacher gewartet werden, Kosten weniger Zeit zum programmieren etc. Sonst würden sie in assembler programmieren.

Es kostet oft viel Zeit ein Programm zu vereinfachen.



In der Praxis jedoch wird oft einfach Copy pasted obwohl es am Ende teurer ist. Naja mir egal.
In der Praxis müssen oft auch "Millionen" von Spezialfällen beachtet werden, also wird fleißig rumgehackt. Für eine richtige Lösung mit weniger Zeilen ist keine Zeit, weil Sie komplett anders aussieht.
 
  • Gefällt mir
Reaktionen: Fabii02
Sobald man etwas komplexeres als "hello World" macht :D gilt nunmal 99,999% macht die Wahl des Algorithmus aus und vielleicht 0,001% die Anzahl an genutzen Befehlen.

Man kann eine Such und Sortierfunktion mit 4 Zeilen schreiben die stumpf alles duchläuft oder zig hundert Zeilen für ein B-Tree basiertes System aufwenden.

Und da zig hundertfach grössere schlägt den 4-Zeiler sicher um das hundert oder tausendfache sobald die Datenmengen steigen.
 
  • Gefällt mir
Reaktionen: Fabii02
fgordon schrieb:
Sobald man etwas komplexeres als "hello World" macht :D gilt nunmal 99,999% macht die Wahl des Algorithmus aus und vielleicht 0,001% die Anzahl an genutzen Befehlen.
Das überzeugt mich nicht so richtig, viele Programme bestehen nicht zum überwiegenden Teil aus komplexen oder aufwendigen selbstgebauten Algorithmen. Wer eine Such- oder Sortierfunktion selber implementiert, der macht höchstwahrscheinlich sowieso schon was grundlegend falsch.

Ich würde vermuten, du hast kürzlich AuD im Studium gehört? :P
 
Uh ne da liegst Du gut daneben - vielleicht solltet Du es hier machen wie beim "Programmieren" abwarten bis jemand, der das besser kann was vermutet und Du dann dessen Vermutung einbinden kannst..... :D

Progammieren wird erst doch dann wirklich interessant, wenn es auch über das hinausgeht was jeder kann, Sachen von anderen aneinanderreihen.

Kurzer Code ist letztendlich keine so grosse Kunst das ist eher einfaches Handwerk, das nutzen ja fast alle Compiler intern wemnn sie optimieren - kurze Laufzeit bei etwas komplexeren Aufgaben, das ist das was entscheidend ist.

Codeoptimierung ist nunmal das, was am Wenigsten wichtig ist - Wie löse ich das Problem XY am Effektivsten das ist das wo es sich lohnt zu optimieren - völlig unabhänig von der genutzen Programmiersprache.
 
  • Gefällt mir
Reaktionen: RalphS
BeBur schrieb:
Wer eine Such- oder Sortierfunktion selber implementiert, der macht höchstwahrscheinlich sowieso schon was grundlegend falsch.
Genau. Ich habe einen b-tree das erste und letzte mal in meinem Leben ca. 1986 in der Übung zur entsprechenden Vorlesung in Pascal selber implementiert.
Es gibt sicher schon mal Fälle wo die Implementierung von Basis-Datenstrukturen zu Fuß sinnvoll ist, z.B. eine einfache verkettete Liste in einem bare-metal C Programm.

Aber eigentlich sind solche Diskussionen, wie diese hier, rein akademischer Natur.
Die Praxis der Softwareentwicklung besteht zu 90% aus Wartung von existierenden Codebasen, die in der Regel wenig konsistent sind, da über die Jahre Leute mit sehr unterschiedlichen Vorstellungen und sehr unterschiedlichen Skills geschrieben wurden. Man darf auch nicht vergessen, das erhebliche Mengen an Code (wenn nicht sogar der überwiegende Teil) von Quereinsteigern geschrieben werden, also Leuten die nicht originär Informatik studiert haben sondern irgendwas anderes.
 
  • Gefällt mir
Reaktionen: Quonux, Skysnake und BeBur
Der B-Tree ist doch nur als Beispiel zu sehen, der beweist wie ein deutlich mehr an "intelligentem" Code die Laufzeit extremst positiv verändern kann.

Wenn ich sage ein Algorithmus der 80% bereits im Vorfeld herausfiltert, wenn der mehr Zeilen hat ist trotzdem sicher oft sinnvoller als möglichst kurzer Code, der das nicht macht - muss ich dann für manche wirklich extra dazuschreiben das ist selbstverständlich nur exemplarisch, das gilt natürlich auch im Konkreten evtl von vielleicht 25% bis 79,9% und von 80,1% bis 100%

Weil sonst jemand kommt der die dahinterliegende grundsätzliche Aussage nicht versteht und das wörtlich nimmt und sagt ja aber mooooment, dass man genau 80% herausfiltern kann, das kommt doch voll selten vor.... :D

Sich das Untere als Vorbild zu nehmen ist nie eine gute Idee, das ist dann wie wenn jemand Marathon laufen will und gleich von Anfang an sagt ja aber Moment der 350 kg Mann der maximal 3 Schritte gehen kann und sich dann setzen muss, weil er ausser Atem ist, der ist jetzt mein Vorbild, der hat nämlich kewle Laufschuhe an.

Wenn man nicht mal besser sein will als das "Unterste" dann ist das doch eigentlich nur Zeitverschwendung? Glaube nicht dass viele damit auf Dauer glücklich werden oder daran Spass haben.
 
Zuletzt bearbeitet von einem Moderator:
fgordon schrieb:
Der B-Tree ist doch nur als Beispiel zu sehen der belegt wie deutlich mehr "intelligenter" Code die Laufzeit extrem positiv verändert.
Das ist schon klar. Es geht eher darum, ob man Anwendungslogik und Basis-Datenstrukturen miteinander vermischt oder ob man eine Abstraktionsebene einzieht, sprich man hat eine Basis-Bibliothek die Datencontainer in abstrakter Form implementiert und den Anwendungscode, der nur diese Library nutzt. Dann ist dieser Anwendungscode unter Umständen sogar kürzer als eine "naive" Implementierung.
Idealerweise definieren die Container Klassen der Verhalten nach "außen", ob sie intern z.B. einen Tree oder eine Hashtabelle benutzen, verstecken sie.

Es gibt aber in der Praxis jede Menge Code (besonders in Sprachen wie C, die von Hause aus keine entsprechende Funktionalität in ihrer Standard-Library bieten) der diese Trennung nicht vornimmt (Stichwort: Separation of Concerns).
 
Jede Abtraktionsbene, die man entwickelt ist das KOMPLETTE Gegenteil von möglichst kurzem Code. Sie ist nur im extremsten Ausnahmefall identisch mit dem küzesten Code in 99,9999999999% :D der Fälle ist eine Abstraktionsebene zusätzlicher Code - denn das ist deren Sinn eine zusätzliche Schicht für z.B. die einfache Mehrfachverwendbarkeit dazwischenzuschieben.

Wenn Du 10.000 Zeilen für eine Abstraktionsbene entwickelst und Du die mit 2 Zeilen im Hauptprogamm aufrufst hast Du 10.002 Zeilen Code dafür entwickelt und nicht 2. Und wenn die Abstraktionsebene auch was taugt und nicht nur nutzloser Müll ist, werden die 10.000 Zeilen auch dort zum Grossteil durchlaufen - irgendwann in der Programmausführung.

Nur weil man was verpackt und auslagert ist das nicht "weg".
 
Zuletzt bearbeitet von einem Moderator:
  • Gefällt mir
Reaktionen: Skysnake
fgordon schrieb:
Kurzer Code ist letztendlich keine so grosse Kunst das ist eher einfaches Handwerk, das nutzen ja fast alle Compiler intern wemnn sie optimieren
Das ist eine etwas seltsame Aussage in mehrerlei Hinsicht. Moderne Compiler wirst du imHo selten schlagen was reine Code-Optimierung angeht. Compiler verkürzen Code darüber hinaus auch nicht (zwangsläufig). Zumindest LLVM transpiled erst in IR vor dem Optimieren, also verkürzt "den code" selber gar nicht. Darüber hinaus schrieben hier ja schon mehrere, dass ein Grund für kompakten Code die Verständlichkeit ist und das hat mit Compilern nichts zu tun.

fgordon schrieb:
Uh ne da liegst Du gut daneben - vielleicht solltet Du es hier machen wie beim "Programmieren" abwarten bis jemand, der das besser kann was vermutet und Du dann dessen Vermutung einbinden kannst.....
fgordon schrieb:
Wenn man nicht mal besser sein will als das "Unterste" dann ist das doch eigentlich nur Zeitverschwendung? Glaube nicht dass viele damit auf Dauer glücklich werden oder daran Spass haben.
Kannst du Beispiele aus der Praxis nennen? Ich kenne das so, man entwickelt die Software und wenn es irgendwo einen Flaschenhals geben sollte, dann kann es sein, dass man sich die betroffene Stelle anschaut um diese zu optimieren. Je nach Anwendung kann das ein SQL Query sein, das kann eine langsame Operation sein (z.B. ein mapping über eine Objektliste) oder sonstwas. Nichts davon würde ich zumindest jetzt als "Algorithmus wählen" bezeichnen, da keine Algorithmen im engeren Wortsinne betroffen sind.
Ich persönlich entwickel selber auch Algorithmen, und arbeite an Software mit, die vornehmlich Algorithmen ausführt. Die sind allerdings nicht zeitkritisch, also selbst in diesem doch recht kleinen Teilbereich der Softwareentwicklung komme ich eher selten in die Verlegenheit, einen Algorithmen umschreiben zu müssen, weil er zu langsam ist.
Man darf auch nicht vergessen, sehr viele arbeiten mit Python, R oder andere interpretierten Sprachen. Das ist dann oft eher Glue-Code (z.B. im Bereich Machine Learning) und das zeigt eigentlich schon, dass Performance nicht so dramatisch im Vodergrund steht, wie du das implizierst. Höchstens einzelne Teile mal.

Keine Ahnung in welchem Bereich du arbeitest, aber deine Perspektive, dass die meisten Softwareentwickler damit beschäftigt sind, Algorithmen zu wählen oder gar anzupassen finde ich schon eher seltsam.

fgordon schrieb:
ede Abtraktionsbene die man entwickelt ist das KOMPLETTE Gegenteil von möglichst kurzem Code.
Abstraktion und kluge Organisation (im Sinne von Entkoppelung z.B.) sind eher Fragen von Software-Architektur und da geht es dann nicht mehr um Code-Zeilen.
 
  • Gefällt mir
Reaktionen: TomH22
fgordon schrieb:
Jede Abtraktionsbene, die man entwickelt ist das KOMPLETTE Gegenteil von möglichst kurzem Code.


Der "Code der durchlaufen wird" ist ja nicht gleichzusetzen mit meinem eigenen Code den ich warten und betreuen muss. Das berühmte Hello-World Programm nutzt auch die Abstraktion "printf" (oder das entsprechende Äquivalent in einer anderen Programmiersprache). Und je nach C-Library werden auch gerne mal 50-100KB Library Code eingebunden. Aber was hat das für eine Relevanz für die Länge/Komplexität des Hello-World Programs?

Auch dem TE ging es bei der Ausgangsfrage vermutlich um die Länge der von ihm geschriebenen Lösung für ein bestimmtes Problem. Und klar, man darf da nicht Äpfel mit Birnen vergleichen (also z.B. lineare Suche mit Tree-Suche). Aber bei einem gegebenen Problem unterscheiden sich Lösungen verschiedener Programmierer häufig bezüglich Codelänge, Übersichtlichkeit, Korrektheit auch in Edge Cases, und Performance. Das gilt natürlich besonders bei den Übungslösungen in einer Hochschul-Vorlesung. Der kürzeste Code kann natürlich auch deswegen kurz sein, weil er z.B. Edge Cases nicht abfängt, dann ist er falsch. Aber es kann auch sein, das ein Programmierer Redundanzen nicht erkennt (z.B. ein booleschen Ausdrücken; banales Beispiel (a!=0 && a>0) ) und dadurch der Code unnötig lang ist, usw.
 
"ob man eine Abstraktionsebene einzieht, sprich man hat eine Basis-Bibliothek die Datencontainer in abstrakter Form implementiert und den Anwendungscode, der nur diese Library...."

und eine Abstraktionsebene, die man selbst entwickelt gehört nunmal zum eigenen Code und wird auch in der Programmausführung durchlaufen.
 
Zuletzt bearbeitet von einem Moderator:
  • Gefällt mir
Reaktionen: KitKat::new()
Ja, aber worauf willst Du hinaus? Es ist schon klar, das eine der Problemstellung nicht angemessene Lösung keine gute Lösung ist, selbst wenn sie dadurch kurz (im Sinne der Codelänge) ist. Aber ich glaube das ist niemals die Fragestellung gewesen. Es geht um die Frage, ob von zwei adäquaten, vollständigen, korrekten und hinreichend performanten Lösungen die "Kürzere" die bessere ist.

Und da würde ich nach 30 Jahren Praxiserfahrung mit eigenem und fremden Code sagen, "in vielen Fällen": ja.
 
  • Gefällt mir
Reaktionen: KitKat::new()
BeBur schrieb:
Man darf auch nicht vergessen, sehr viele arbeiten mit Python, R oder andere interpretierten Sprachen. Das ist dann oft eher Glue-Code (z.B. im Bereich Machine Learning) und das zeigt eigentlich schon, dass Performance nicht so dramatisch im Vodergrund steht, wie du das implizierst. Höchstens einzelne Teile mal.

Abstraktion und kluge Organisation (im Sinne von Entkoppelung z.B.) sind eher Fragen von Software-Architektur und da geht es dann nicht mehr um Code-Zeilen.

Hier geht es abrr um die minimale Codegrösse und da weiss doch jeder, der versteht was eine Abstraktionsschicht ist, dass diese zwingend den Code auf mehr bringt als ein minimaler Code.

Abstraktionsschichten gibt es was Codegrösse angeht nicht umsonst.

Das gesamte Machine Learning ist ein Optimierung per Algorithmus. Man nutzt das Riesen Overhead Monster Neuronale Netze weil man mit der "kleinen" Programmerung nicht mehr weiterkommt.

Und weil der Algorithmus das KI System so entscheidend ist für die Ausführung ist das auch (fast) völlig egal ob das im Interpreter läuft oder kompiliert wird oder sonstwo.
 
Zuletzt bearbeitet von einem Moderator:
Zurück
Oben