Gibt es Fälle in denen eine Switchanweisung performanter als schlau genutze verschachtelte if..else Anweisungen sind?



  • Mit verschachtelten if..else Anweisungen kann man die Anzahl der Abfragen ja manchmal verkleinern.

    z.B. wie in diesem Fall

    Pseudocode

    if(c != klein geschrieben)
    {
       c = groß geschrieben
       if (c == A)
         ausgabe "Ne";
       if (c == B)
         ausgabe "Karamba"; 
      ....
    }
    else
    {
      // c = klein geschrieben
      if (c == a)
         ausgabe "bla";
      if (c == b) 
         ausgabe "Hu";
      ....
    }
    

    Bei Nutzung von Switch würde man das wohl eleganerweise der Übersichtlichkeit wegen eine extra Verzweigung zwisch groß und Kleinschreibung weglassen und einfach nur folgendes schreiben

    switch (c){
      case A: ausgabe "Ne "; break;
      case a: ...//usw.
      case B: ...
      case b: ...
    }
    

    Bei 26*2 Zeichen (falls nur Buchstaben zugelassen sind) währen das bei der Switchanweisung also 52 Abfragen, während sie bei obigem if else Beispiel
    auf 26+1 Abfragen reduziert wären.

    Aber kann es auch vorkommen, daß die Switchanweisung trotzdem performanter ist, obwohl es mehr Abfragen sind?
    Kann die Switchanweisung also vom Compiler z.B. effizienter implementiert werden oder bietet die Hardware dafür spezielle Vorkehrungen?
    AFAIK sind ja z.B. ab Bulldozer bei manchen Opcodes gleich 4 Operanden zulässig
    und wenn bei der Suche nach der größten Zahl von a, b, c, d es z.B. einen Opcode gibt, der einfach "max a, b, c, d" auf einmal in der CPU ausführt, dann könnte man das mit Switch ja gut realisieren, während ein if..else Zweig weiterhin if nur Opcodes mit 2 Operanden wären, die nach der Reihe ausgeführt werden müßten.

    Hat also die Switch Anweisung neben dem Vorteil der leichteren Lesbarkeit auch aus Performancegründen irgendwelche Vorteile?



  • Sry, habe das Kommentarzeichen vergessen, jetzt sollte es stimmen:

    if(c != klein geschrieben)
    {
       // c = groß geschrieben
       if (c == A)
         ausgabe "Ne";
       if (c == B)
         ausgabe "Karamba"; 
      ....
    }
    else
    {
      // c = klein geschrieben
      if (c == a)
         ausgabe "bla";
      if (c == b) 
         ausgabe "Hu";
      ....
    }
    


  • Ok, ich sehe gerade.

    Wenn eine Bedingung gleich am Anfang erfüllt werden kann, z.b. beim A, anstatt beim Z, dann kann die Switch Anweisung sofort (dank break bzw, integrierter Sprunganweisung) abgebrochen werden, während die IF Anweisungen bis zum Z durchprobiert werden.

    So ist switch beim Abbruch natürlich schneller.

    Aber meine Frage bezieht sich eher darauf, wenn an der gleichen Stelle und das erst spät, z.B. beim Z erst die Bedingung erfüllt wird.
    Hätte hier switch dann noch performance Vorteile?



  • Google: switch sprungtabelle

    Außerdem sind so lange if else oder switch oft ein Zeichen für Designfehler.



  • 123... schrieb:

    Außerdem sind so lange if else oder switch oft ein Zeichen für Designfehler.

    Schon klar, nur viel mir momentan kein besseres Beispiel ein.

    Wie muß ich mir eine Sprungtabelle intern vorstellen?
    Von wo weiß das Programm, wo es hinspringen soll, wenn z.B. case Z: ausgelöst werden soll?
    Wie genau wird switch(c) ausgewertet?



  • switch Anweisung schrieb:

    Wie muß ich mir eine Sprungtabelle intern vorstellen?

    ein zeigerarray 🙄

    switch Anweisung schrieb:

    Von wo weiß das Programm, wo es hinspringen soll, wenn z.B. case Z: ausgelöst werden soll?

    bei array+z steht die adresse, an der es weiter geht 😉

    switch Anweisung schrieb:

    Wie genau wird switch(c) ausgewertet?

    kommt auf deinen compiler und die verwendeten werte an, am besten keine bzw. mögl. kleine lücken lassen 😃



  • King George schrieb:

    switch Anweisung schrieb:

    Wie muß ich mir eine Sprungtabelle intern vorstellen?

    ein zeigerarray 🙄

    Ok.
    Aber wie weiß das Programm, an welche Adresse es springen soll, also welcher Zeiger relevant wird?
    Siehe nächster Punkt:

    switch Anweisung schrieb:

    Von wo weiß das Programm, wo es hinspringen soll, wenn z.B. case Z: ausgelöst werden soll?

    bei array+z steht die adresse, an der es weiter geht 😉

    Ist Z ein nummerischer Wert?

    Oder wie meinst du das, Array mit Z addieren?

    switch Anweisung schrieb:

    Wie genau wird switch(c) ausgewertet?

    kommt auf deinen compiler und die verwendeten werte an, am besten keine bzw. mögl. kleine lücken lassen 😃

    Was meinst du mit Lücken?



  • switch Anweisung schrieb:

    Ist Z ein nummerischer Wert?

    ja, also bei mir schon. sonst fällt die sprungtabellen optimierung raus.(eig. stimmt es nicht ganz, aber das geht jetzt zu weit...)

    switch Anweisung schrieb:

    Was meinst du mit Lücken?

    case 1:
    case 2:
              //<<lücke
    case 4:
    


  • King George schrieb:

    switch Anweisung schrieb:

    Ist Z ein nummerischer Wert?

    ja, also bei mir schon. sonst fällt die sprungtabellen optimierung raus.(eig. stimmt es nicht ganz, aber das geht jetzt zu weit...)

    Wann wäre Z kein nummerischer Wert?

    switch Anweisung schrieb:

    Was meinst du mit Lücken?

    case 1:
    case 2:
              //<<lücke
    case 4:
    

    Ok, verstehe, aber wenn Z ein nummerischer Wert ist und es in meinem Programm nur
    case A
    case M
    und
    case Z

    geben würde, dann würden die 3 Zeichen doch einfach ab 0 bis 2 durchnummeriert werden, oder?

    Das Problem mit Lücken trifft also nur bei Zahlen im case Teil auf, richtig?



  • switch Anweisung schrieb:

    Wann wäre Z kein nummerischer Wert?

    In den meisten Sprachen darf das Argument einer switch Anweisung sowieso nur ein numerischer Wert sein.

    switch Anweisung schrieb:

    Ok, verstehe, aber wenn Z ein nummerischer Wert ist und es in meinem Programm nur
    case A
    case M
    und
    case Z

    geben würde, dann würden die 3 Zeichen doch einfach ab 0 bis 2 durchnummeriert werden, oder?

    Meinst Du 'A', 'M' und 'Z'? Auch dies sind numerische Werte, nur als ASCII-Zeichen ausgedrückt. Hier könnte eine Sprungtabelle mit 256 Einträgen erstellt werden, won denen 253 einfach hinter die switch-Anweisung verzweigen.



  • switch-case funktioniert (zumindest in C und C++) nur mit numerischen Datentypen (auch char ist numerisch ;)).

    Ansonsten:
    Beim switch wird der Compiler vermutlich eine Umrechnung suchen, die deine case-Labels möglichst kompakt (und eindeutig) auf den Bereich 0..n abbildet. Damit baut er dann ein Array, wo an Position f(x) die Adresse der Anweisung hinter dem "case x:" steht. Lücken in den Labels dürften da höchstens etwas Speicherplatz verbrauchen, aber effektiv brauchst du nur eine Umrechnung und einen Sprung, um im richtigen Zweig zu landen.
    Bei der if-else Kaskade müssen wirklich alle Bedingungen der Reihe nach abgefragt werden, bis eine davon erfüllt wurde, bei deiner Konstruktion (ohne else in den inneren Blocks) sogar alle Abfragen, selbst wenn du weißt, daß sie gar nicht mehr benötigt werden.



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Rund um die Programmierung in das Forum C++ (auch C++0x, bzw. C++11) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Was hat das Thema in C++ zu suchen?

    Switch und if..else sind ein Programmierkonzept, darauf zielt auch die Frage ab und hat nur eingeschränkt etwas mit C++ zu tun.



  • Falsches Forum schrieb:

    Was hat das Thema in C++ zu suchen?

    Switch und if..else sind ein Programmierkonzept, darauf zielt auch die Frage ab und hat nur eingeschränkt etwas mit C++ zu tun.

    Das Optimierungspotential und die Implementierung sind aber von der Sprache abhängig! Ein switch in C# kann mit string umgehen. In C++ ist das nicht möglich.



  • jkljkljkl schrieb:

    Falsches Forum schrieb:

    Was hat das Thema in C++ zu suchen?

    Switch und if..else sind ein Programmierkonzept, darauf zielt auch die Frage ab und hat nur eingeschränkt etwas mit C++ zu tun.

    Das Optimierungspotential und die Implementierung sind aber von der Sprache abhängig! Ein switch in C# kann mit string umgehen. In C++ ist das nicht möglich.

    Ja und? Also sind wir dann einfach bei der Frage, ob die Strings dann nummerisch sind.



  • Ich glaube er meinte sowas wie Duff's Device.


Anmelden zum Antworten