Forum: Compiler & IDEs if oder swich?


von FlorianV (Gast)


Lesenswert?

Hallo Freunde,
Blöde Frage, einfache Antwort reicht :)
Was ist besser/schneller/eleganter: ein if/elseif Verhau oder switch 
Anweisung?
Gruss,
Flo

von (prx) A. K. (prx)


Lesenswert?

Was ist besser/schneller/eleganter: Flugzeug, Auto, Fahrrad oder zu 
Fuss?

von der Hirte (Gast)


Lesenswert?

FlorianV schrieb:
> Blöde Frage, einfache Antwort reicht
Ja nach Anwendungsfall das eine oder das andere. :)

von Klaus W. (mfgkw)


Lesenswert?

wenn beides geht, ist meist eher das switch angemessen.

von Oliver (Gast)


Lesenswert?

Bei einem einigermassen "intelligenten" Compiler sollte es da gar keinen 
Unterschied geben.

Aber wenn du es genau wissen willst, schau dir halt an, was dein 
Compiler draus macht.

Oliver

von FlorianV (Gast)


Lesenswert?

Ja schon klar, ist wirklich ne blöde Frage...
Ich sag mal was ich damit vorhabe. Compiler output schau ich mir aber 
auch mal an und vergleich das mal...

Ein Timer zählt ein Byte hoch und bei jedem "step" soll eine andere 
Anweisung ausgeführt werden:
1
if (step == 0){
2
 a = 120;
3
 b = x;
4
 c++; 
5
}else if (step == 1 {
6
 a = 134;
7
 b = y;
8
 c--; 
9
}
10
.
11
.
12
.

Switch währe deutlich übersichtlicher bei vielen steps. Oder gibts da 
noch bessere Wege?

Gruss,
Flo

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

FlorianV schrieb:
> Switch währe deutlich übersichtlicher bei vielen steps.

Dann benutze einen Switch.

Never try to optimize before you have profiled it.

Mit anderen Worten: Gedanken darüber, ob der Compiler irgendeine
der Varianten effizienter umsetzt machst du dir erst dann, wenn sich
rausstellt, dass die gewählte Variante zum Nadelöhr wird.  Bis dahin
ist es erst einmal wichtiger, einen möglichst übersichtlichen
Sourcecode zu haben.

von Werner (Gast)


Lesenswert?

FlorianV schrieb:
> Switch währe deutlich übersichtlicher bei vielen steps. Oder gibts da
> noch bessere Wege?

Du kannst mit steps auch direkt über ein Array von Funktions-Pointern 
die auszuführende Funktion aufrufen

von Lukas (Gast)


Lesenswert?

Werner schrieb:
> Du kannst mit steps auch direkt über ein Array von Funktions-Pointern
> die auszuführende Funktion aufrufen

Oder noch eleganter, die Parameter für eine allgemeine Funktion aus 
einem Array holen, wenn die Funktionen ganug ähnlich sind.

lg

von FlorianV (Gast)


Lesenswert?

Hi,
Danke für die vielen Antworten.

>Du kannst mit steps auch direkt über ein Array von Funktions-Pointern
>die auszuführende Funktion aufrufen

Klingt sehr umständlich :)

>wenn die Funktionen ganug ähnlich sind.

Sind sie nicht :(

Macht aber nix, ich mach erstmal und sehe wie weit ich komme. Die 
Performance ist eh nicht kritisch und wenn der Speicher voll ist, ist er 
halt voll...

Gruss,
Flo

von Peter D. (peda)


Lesenswert?

Wenn switch geht, dann nimm switch.
Switch wird in der Regel deutlich besser optimiert.
Und lesbarer ist es obendrein.
Der AVR-GCC gestattet sogar switch mit Bereichen:
1
  case 5 ... 45:


Peter

von Rolf M. (rmagnus)


Lesenswert?

Peter Dannegger schrieb:
> Der AVR-GCC gestattet sogar switch mit Bereichen:
>  case 5 ... 45:

Das untestützt jeder gcc. Allerdings ist es kein Standard-C.

von superstru (Gast)


Lesenswert?

sprungtabellen nicht vergessen!
die gibts ja auch noch als alternative zu nem switch :D

und bei if/switch kommt ja noch verschachteln hinzu, und das arrangement 
(häufige sachen zuerst testen, seltenes dann in extra switch statement 
im default des höheren switch usf)

von (prx) A. K. (prx)


Lesenswert?

"if" Kaskaden haben gegenüber sie ebenfalls abdeckenden "switch" einen 
Vorteil: Man kann auch ohne profile guided optimization die Reihenfolge 
der Tests optimieren. Wenn die Vergleiche stark von einige wenige Fällen 
dominiert werden, dann kann sich das u.U. auswirken. Allerdings ist das 
schon ein recht extremer Fall und es ist fast immer unsinnig, sich davon 
leiten zu lassen.

von (prx) A. K. (prx)


Lesenswert?

Lukas schrieb:

> Oder noch eleganter, die Parameter für eine allgemeine Funktion aus
> einem Array holen, wenn die Funktionen ganug ähnlich sind.

Was auf leistungsfähigen Prozessoren der PC/Server-Klasse den Vorteil 
hat, ohne schwer vorhersagbare Sprünge auszukommen. Die gehören zu den 
grössten Rechenbremsen solcher Prozessoren. Folglich kann eine Lösung 
ohne bedingte oder indirekte Sprünge trotz komplexerer Arbeit schneller 
sein als ein auf einem indirekten Sprung oder einem Abfragebaum 
basierendes "switch" Statement. Auf einfach gestalteten Controllern ist 
es dann umgekehrt, was allgemeine Leitlinien erschwert.

von Rolf M. (rmagnus)


Lesenswert?

superstru schrieb:
> sprungtabellen nicht vergessen!
> die gibts ja auch noch als alternative zu nem switch :D

Und wie willst du die in C implementieren? Abgesehen davon macht gcc aus 
einem switch automatisch eine Sprungtabelle, wenn es sinnvoll ist.

> und bei if/switch kommt ja noch verschachteln hinzu, und das arrangement
> (häufige sachen zuerst testen, seltenes dann in extra switch statement
> im default des höheren switch usf)

Wer macht denn sowas?

von (prx) A. K. (prx)


Lesenswert?

Rolf Magnus schrieb:

> Und wie willst du die in C implementieren?

Natürlich so:
1
   static void *table[] = { &&case0, &&case1, ... };
2
   goto *table[i];
3
case0:
4
   ...
5
case1:
6
   ...

von Rolf M. (rmagnus)


Lesenswert?

Ach so, also auch mit einer GCC-Erweiterung. Ich hab mir zur Regel 
gemacht, die nicht zu verwenden, wenn's auch ohne geht.

von (prx) A. K. (prx)


Lesenswert?

Ich habe das auch nie verwendet, aber als Antwort auf die Frage kam es 
grad passend. ;-) Vermutlich waren eigentlich function pointer gemeint. 
Der tiefere Sinn dieser Erweiterung erschliesst sich mir ohnehin nicht.

von Klaus W. (mfgkw)


Lesenswert?

A. K. schrieb:
> Der tiefere Sinn dieser Erweiterung erschliesst sich mir ohnehin nicht.

In handgeschriebenem Code würde ich es mir auch schwer überlegen, so 
etwas zu verwenden,
Aber ich kann mir schon sinnvolle Anwendungen denken, z.B. maschinell 
erzeugten Code aus Zustandstabellen oder ähnliches.

Nachdem es wohl leicht im Compiler einzufügen war, warum nicht?

Außerdem kann man dann nochmal wehmütig über das gute alte Fortran 
sinnieren mit dem berechneten GOTO:
1
      IF( IRGEND + WAS ) 100, 200, 300
2
3
100   ...
4
5
200   ...
6
7
300   ...

Wenn der Ausdruck 1 ergibt, wird zum ersten Label (100) gesprungen, bei 
2 zum zweiten etc.; bei anderen Werten passiert irgendwas richtig 
spannendes.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Wenn der Ausdruck 1 ergibt, wird zum ersten Label (100) gesprungen, bei
> 2 zum zweiten etc.; bei anderen Werten passiert irgendwas richtig
> spannendes.

Waren die Labels nicht für expr < 0, expr == 0, expr > 0?

Auf jeden Fall eins der Lieblingskonstrukte für `Real Programmers'. :)
Man muss es allerdings passend mit EQUIVALENCE-Listen zusammenmischen,
damit die gewünschte Arbeitsplatzsicherung daraus entsteht.  Auch
handausgezählte Hollerith-Konstanten, bei denen man sich geschickt
so verzählt, dass nicht auffällt, dass die nächsten Zeichen schon eine
neue Bedeutung bewirken, machen sich da gut. >:-)

von Klaus W. (mfgkw)


Lesenswert?

Jörg Wunsch schrieb:
> Waren die Labels nicht für expr < 0, expr == 0, expr > 0?

Peinlicherweise muß ich dir da auch noch Recht geben.
Ich hatte das mit dem berechneten GOTO verwechselt:
    GOTO (100,200,300)  IRGEND + WAS

War schon eine krude Sprache....

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.