Welcher if Syntax ist schneller?

Hallo,

... weiß das jemand?

if ( c == 1 ) {
  //
}
if ( c == 2 ) {
  //
}
if ( c == 3 ) {
  //
}

oder

if ( (c == 1) || ( c == 2 ) || ( c == 3 ) ) {
  //
}

Der Compiler optimiert da sowieso

Aber dank Kurzschlussauswertung bricht die Oder-Verküpfung ab sobald eine Bedingung wahr ist

Die beiden Kodes haben keine unterschiedliche Syntax, aber einen völlig anderen Aufbau.

  1. drei voneinander unabhängige Abschnitte die ausgeführt werden, wenn ihre Bedingungen erfüllt sind
  2. ein Abschnitt der ausgeführt wird, wenn eine der Bedingungen erfüllt ist.

Also im Fall 2 die Bedingung, deren Eintreten am wahrscheinlichsten ist (bzw. die öfter eintritt) nach links.

Im Gegesatz dazu die unwahrscheinlichste bei AND nach links.

Gruß Tommy

Whandall:
Die beiden Kodes haben keine unterschiedliche Syntax, aber einen völlig anderen Aufbau.

Die unterschiedliche Bedeutung der Codes hat mich auch irritiert.

Um unterschiedliche Laufzeiten zu ermitteln, würde ich entweder die beiden Varianten gleich oft aufrufen und die Ausführungsdauer vergleichen - oder mir den erzeugten Assemblercode ansehen und die jeweils benötigte Taktanzahl vergleichen.

Wichtiger ist aber, für solche Messungen bedeutungsgleiche Codes zu verwenden :slight_smile:

Gruß

Gregor

Hallo,

es geht um die Fehlerbehandlung der UART. Das heißt die Fehlerabfrage wird wohl nie oder zu 99,99999% nie wahr werden. Also im Normalfall wird nichts dessen wahr. Deswegen möchte ich das diese Abfragen bzw. die eine Mehrfachabfrage so schnell wie möglich abgebrochen werden. Wenn eine Bedingung wahr wäre, kann das meintwegen so lange dauern wie es möchte, übertrieben gesagt. Ansonsten sollte das so schnell wie möglich durchrasseln.

Bei der ersten Variante würden alle hintereinander sofort abgebrochen. Es müßte jedoch 3x hintereinander abgebrochen werden.
Bei der zweiten Variante müßte eigentlich auch 3x hintereinander geprüft werden, weil ODER verknüpft.
Ich merke schon, wenn das der Compiler selbst optimiert ist es bestimmt gehüpft wie gesprungen.
Irgenwas mit negieren abzufragen damit schneller abgebrochen wird ergibt aktuell in meinem Kopf auch keinen Sinn.
Also kann ich das schreiben wie ich möchte?

Also kann ich das schreiben wie ich möchte?

Du könntest dir den generierten Assemblercode anschauen.

Ich persönlich halte das für Mikrooptimierung.

Gibt es auch einen Returncode für alles ok? Dann könnte man den ja als übergeordnete Abfrage laufen lassen.
Sorry, dass ich das so allgemein formuliere. Mehr Infos waren nicht enthalten.

Gruß Tommy

Hallo,

es kann durchaus sein das es "Mikrooptimierung" ist. Aber das weiß ich ja nicht. Deswegen frage ich. Wenn das 0,1ms spart wäre das schon eine Hausnummer die ich gern mitnehme. Anfrage kommt rein, wird abgearbeitet, Antwort geht raus. Je schneller das abläuft umso besser.

Ich habe mich aktuell nur mit den Fehlercodes befasst. Ob es auch ein OK gibt habe ich nicht bewusst gelesen. Ich denke nicht. Ich lese das aber gern nochmal. Aktuell ist es demnach egal wie. Der Forscherdrang kommt langsam wieder durch. Durch solchen "Kleinkram" lernt man ja auch. :slight_smile:

Ich danke erstmal allen für die Denkanstöße.

Doc_Arduino:
... Der Forscherdrang kommt langsam wieder durch. Durch solchen "Kleinkram" lernt man ja auch. :slight_smile:

Als Forscher würde ich das möglichst realitätsnah austesten. Also sehr oft ablaufen lassen und die Zeiten vergleichen. Wenn Du mehrere Arduinos oder wasauchimmer hast, würde ich die auch gegeneinander antreten lassen. Ich finde immer noch erstaunlich, wie unterschiedlich schnell die sein können.

Gruß

Gregor

Ein probates Mittel um Abfragen einzusparen, sind Lookup Tables.
In diesem Fall könnte das eine Sprungtabelle sein.

Hallo,

switch case legt Sprungtabellen an soviel ich weiß. Ich werde das morgen mal alles austesten.

hi,

also nach meiner meinung hat serenifly die frage schon in der ersten antwort geklärt.

gruß stefan

Hallo,

wenn immer etwas wahr wäre, dann hätte Serenifly damit alles erschlagen. Im Normalfall wird jedoch nichts wahr und dennoch muss alles abgefragt werden. Genau das ist der kleine aber feine Unterschied. Okay ich muss zugeben das es aus der Eingangsfrage nicht hervor ging. Sorry.

hi,

das sorry muß von mir kommen, weiter unten hattest Du es ja geschrieben...

willst Du denn wirklich wissen, daß c ungleich 1 und 2 und 3 ist, oder sind das nur hausnummern für das beispiel?

gruß stefan

Doc_Arduino:
Bei der ersten Variante würden alle hintereinander sofort abgebrochen. Es müßte jedoch 3x hintereinander abgebrochen werden.

Das ist eine der wenigen Fälle wo mal ein goto nicht unbedingt verkehrt ist:

if (c == ...)
{
   ERROR_CODE = ...;
   goto ERROR;
}

if (c == ...)
{
   ERROR_CODE = ...;
   goto ERROR;
}


ERROR:
   Serial.println(ERROR_CODE);
   return;

hi,

macht aber auch nichts anderes als die zeile mit den beiden OR. bricht also nach dem ersten treffer ab.
außerdem tritt der fall, daß es einen treffer gibt, fast nie ein, es werden also praktisch immer alle drei vergleiche durchgeführt.

interessant wäre, ob es wirklich nur um EIN c geht, das verglichen werden muß, und falls ja, welche werte richtig wären und welche falsch. vielleicht kann man da ja auf binärer ebene etwas tricksen...

gruß stefan

es geht um die Fehlerbehandlung der UART. Das heißt die Fehlerabfrage wird wohl nie oder zu 99,99999% nie wahr werden. Also im Normalfall wird nichts dessen wahr. Deswegen möchte ich das diese Abfragen bzw. die eine Mehrfachabfrage so schnell wie möglich abgebrochen werden.

if(c) // dann Fehlerbehandlung 
{
  switch(c)
  {
     case 1: // konkrete Fehlerbehandlung
     case 2: // konkrete Fehlerbehandlung
     case 3: // konkrete Fehlerbehandlung
  }
}

Doc_Arduino:
switch case legt Sprungtabellen an soviel ich weiß.

Schön, dass das Leben so einfach nicht ist.
Wenn du auf Speed optimieren lässt, wird es das tun, wenn denn die anderen Randbedingungen stimmen.
Wenn du auf Size optimierst, welches die Arduino default Einstellung ist, dann eher nicht.

Sprungtabellen kann man mit computed Goto erzwingen. Macht z.B. Sinn, in endlichen Automaten(Schrittketten), um lange Switch-Case Konstrukte zu ersetzen.

0,1ms sollte sowas nicht dauern, eher um Größenordnungen kurzer.

If (c!=0) könntest du auch mal austesten. Wenn du dann doch verschiedene Fehlerbehandlungen machen willst, danach erst in die switch case rein

If (c!=0)
If (c)
Ist beides das gleiche