Hallo Freunde, Blöde Frage, einfache Antwort reicht :) Was ist besser/schneller/eleganter: ein if/elseif Verhau oder switch Anweisung? Gruss, Flo
FlorianV schrieb: > Blöde Frage, einfache Antwort reicht Ja nach Anwendungsfall das eine oder das andere. :)
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
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
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.
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
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
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
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
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.
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)
"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.
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.
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?
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 | ...
|
Ach so, also auch mit einer GCC-Erweiterung. Ich hab mir zur Regel gemacht, die nicht zu verwenden, wenn's auch ohne geht.
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.
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.
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. >:-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.