Berechnungsstrategie

Bennyaa

Lieutenant
Registriert
März 2007
Beiträge
828
Hallo,
ich stelle mal eine grundlegende Frage:
Würdet ihr eine Berechnung aufgrund einer Bedingung eher in der Formel ändern, oder die Parameter anpassen?
Bsp.
Code:
if(bedingung)
{
  erg = a + b;
}
else
{
  erg = a + b + c;
}

oder lieber:

Code:
if(Bedingung)
{
  c = 0
}

 erg = a + b + c;
 
variante 2, weil kein duplizierter code (siehe dry). alternativ eine funktion dafür:
Python:
def add(a, b, c=0):
    return a + b + c

x = add(1, 2)
y = add(1, 2, 3)
 
  • Gefällt mir
Reaktionen: BeBur, jb_alvarado, Raijin und 3 andere
Über die Parameter bist Du teils etwas flexibler, aber machbar ist Beides.
Kommt auch darauf an, wie komplex die Bedingungen und Formeln sind und vor allem in Zukunft werden können.
Und ohne gute Dokumentation wirst Du im Lauf der Zeit mit beiden Methoden Probleme bei Änderungen bekommen. ;)
 
  • Gefällt mir
Reaktionen: netzgestaltung und PHuV
letzteres, weil du damit automatisch unabhängiger wirst.

wenn sich die Berechnung mal ändern sollte musst im 1.Fall beide (oder 3, oder 4, oder 1000) if-Rechnungen anpassen.
im 2. Fall. nur die letztes zeile.

Was anderes ist es, wenn die Berechnungen undurchführbar werden (zB Division durch 0), aber da kann man entsprechend reagieren.
 
Würde auch zweites machen. Da kann man im Bedarfsfall später viel einfacher weitere Bedingungen hinzufügen usw.
 
Es ist eine philosophische Frage. Willst du maximale Ausführunggeschwindigkeit (Mikrooptimierung! Effekt ist gering), dann versuchst du IF-Anweisungen zu vermeiden. Grundsätzlich empfiehlt es sich, den code so zu schreiben, dass er gut lesbar ist.
 
  • Gefällt mir
Reaktionen: Harti61
Kommt halt auf die Anforderung drauf an. Wenn man mit 3 Termen auskommt würde ich auch die zweite Methode nutzen.
Falls das ganze jedoch dynamisch sein soll. Dann würde ich die Summanden in einen Vector bzw. Liste packen. Dann kann man sich die ganze Bedingung sparen und alle enthaltenen Elemente mit einer Kopfgesteuerten Schleife einfach nacheinander addieren (Ergebnis vorher mit 0 initialieren, dass es nicht kracht sobald kein Element vorhanden ist).
 
Code:
erg = a + b;

if(bedingung)
{
  erg += c;
}
(finde ich besser als indirekt durch Setzen auf 0)
 
  • Gefällt mir
Reaktionen: ZuseZ3, bog, BAGZZlash und 3 andere
KitKat::new() schrieb:
Code:
erg = a + b;

if(bedingung)
{
  erg += c;
}
(finde ich besser als indirekt durch Setzen auf 0)
Die Form hätte ich auch gewählt. 👍

1) ist besser, wenn es wirklich entweder oder mit Ausschließlichkeit sein soll.
Variante 2) ist nur dann sinnvoll, wenn der Code am Ende IMMER ausgeführt werden soll, egal was die Bedingung sagt.
Daher, es kommt darauf an, was genau die Absicht dahinter steckt.
 
  • Gefällt mir
Reaktionen: netzgestaltung und Harti61
Der Code wird immer ausgeführt.
Allerdings ist es eine wesentlich komplexere Berechnung als die hier als Beispiel aufgezeigte,
wodurch

Code:
erg = a + b;

if(bedingung)
{
  erg += c;
}
(finde ich besser als indirekt durch Setzen auf 0)

nicht gut umzusetzen ist, da sich der betreffende Parameter mitten in deiner komplexen verschachtelten Berechnung befindet.
 
Bennyaa schrieb:
Stimmt, aber wird auch schnell unübersichtlich finde ich.

Dann ggf. mit Zwischenergebnissen arbeiten, z.B.
ZwErg1 = Berechnung der statischen Werte
ZwErg2 = Berechnungen, deren Bedingen voneinander abhängen oder ähnlich sind
ZwErg3 = Berechnungen der Sonderfälle
Und am Ende alle Teilergebnisse zusammenführen
 
  • Gefällt mir
Reaktionen: PHuV und Bennyaa
Bennyaa schrieb:
Stimmt, aber wird auch schnell unübersichtlich finde ich.
Dann muss man halt schauen wie man trotzdem die Übersicht behält. Da muss jeder für sich sein Individuelles System für finden.

So gehe ich normalerweise bei meinem Entwürfen unter MATLAB oder C++ vor:
Ich mache zuerst einfache quick and diry Lösungen um zu schauen ob das so grob funktioniert wie ich mir das gedacht hatte.
Dann übelege ich wie ich das, falls möglich objektorientiert, strukturieren kann. -> Zeichne mir die Struktur bei aufwendigen Sachen auf Papier oder mit OneNote auf'm Tablett.
Wenn die Struktur soweit steht schaue ich anschließend noch wo es Sinn macht bestimmte Abschnitte in zusätzliche Funktionen auszulagern, um das ganze für mich übersichtlicher zu gestallten.

Bei mir sieht sowas dann idr. so aus, dass man anhand vom Kommentar weiß was die Funktion machen soll (wie genau ist hier egal, das steht dann im Kommentar der Funktion). Zudem sieht man was wird übergeben bzw. was wird zurück gegeben. Sowas ist für mich halt Übersichtlicher als einfach alles in 'main' bzw. eine große Funktion gepackt.
C++:
// Funktion zur Berechnung von foo
foo = myFunc(&Errorflag, &Parameters);

// Funktion zum Auswerten von foo
myAnalyze(&Errorflag, &foo);

Falls das so halt nicht möglich ist würde ich versuchen den Code mit Abstand zwischen bestimmten Abschnitten zu sortieren und bei komplexen auf jedenfall eine großes Kommentarfeld mit vernünftiger Beschreibung zu dem nachfolgenden Abschnitt zu schreiben, sodass ich in einem halben Jahr oder später nicht davor Sitze und am rätseln bin was der Code genau macht.

C++:
/* Funktion zur Berechnung von foo
Beschreibung zur Funktion
*/
foo = ....


/* Funktion zum Auswerten von foo
Beschreibung zur Funktion
*/
switch(foo) ....
 
  • Gefällt mir
Reaktionen: mercury
Ich würde hier gerne noch ein Gegenbeispiel zu der "nicht duplizieren"-Lösung aufführen.

Bei der Bildbearbeitung muss man oft jeden Pixel anfassen. Da ist ein IF innerhalb einer geschachtelten Schleife durchaus relevant, insbesondere, wenn das Bild 6000x4000 Pixel hat.
Code:
for(var x=0;x<image.width;x++) {
    for(var y=0;y<image.height;y++) {
         // if something
         // do something else
    }
}

Oft sieht man daher Konstruktionen in der Art:

Code:
if(something) {
  for(var x=0;x<image.width;x++) {
    for(var y=0;y<image.height;y++) {
         // do something
    }
  }
} else {
  for(var x=0;x<image.width;x++) {
    for(var y=0;y<image.height;y++) {
         // do something else
    }
  }
}

Das ist dann zwar dupliziert, aber für den speziellen Fall extrem sinnvoll.
 
sandreas schrieb:
Das ist dann zwar dupliziert, aber für den speziellen Fall extrem sinnvoll.
Warum ist das hier sinnvoll? :confused_alt: Der Sinn erschließt sich mir hier nicht.
 
Performance:
  • mehr Code in der Schleife, der auch außerhalb handlebar ist
  • potentielles Branching in der Schleife (schlecht für caching und pipelining in der CPU)

Bekommt man aber auch ohne doppelte Schleife hin ;-)
Und mit etwas Glück wird das sowieso automatisch optimiert.

Mir fehlt eher die Anwendbarkeit aufs Problem vom TE
 
Anhand Deiner spärlichen Konkretisierungen ist das natürlich gar nicht zu beantworten. Es hängt imho zu 100% davon ab, was "Bedingung" ist und wie der Kontext aussieht.
Bennyaa schrieb:
Würdet ihr eine Berechnung aufgrund einer Bedingung eher in der Formel ändern, oder die Parameter anpassen?
Code:
if(bedingung)
{
  erg = a + b;
}
else
{
  erg = a + b + c;
}
oder lieber:
Code:
if(Bedingung)
{
  c = 0
}
 erg = a + b + c;
Hier sieht es so aus, als wäre bedingung ein Skalar oder ließe sich prinzipiell als Skalar ausdrücken. Andere Variante:
Code:
erg = a + b + c * NOT_TRUE_bedingung
könnte "optimal" sein, da vektorisierbar. Man multipliziert also einen Faktor 0 oder 1, den man aus der Bedingung ableitet.
 
  • Gefällt mir
Reaktionen: Schwachkopp
Zurück
Oben