switch-case vs. if-else?



  • sondern das Problem ist dann, dass man in deinem Programm 50 Verzweigungen an einer Stelle hat! Aber das kapiert wohl jemand nicht, der anscheinend wirklich seine Zustandsänderungen hart im Code codiert hat und auch noch stolz darauf ist

    wenn das keine "richtige" Statemachine ist sondern einfach nur viele if-Statements auf einem Haufen könnte ich dir recht geben - aber was ist wenn seine Statemachine wirklich sehr komplex ist - oder mehrere Transitionmatrizen von Hand zusammengefasst sind? Ist ja auch nicht so das wir alle hier immer den gleichen Projekterfahrungshorizont haben

    btw ist es aber für die Performanzfrage auch unrelevant ob es handgeschriebener oder generierter Code ist - und selten(oder nie) switch zu verwenden ist auch irgendwie seltsam/ungewöhnlich



  • SeppJ schrieb:

    Wenn du viele Bedingungen fest im Code stehen hast, machst du wahrscheinlich etwas falsch. Außerhalb von Beispielcodes habe ich jedenfalls noch nie switch benutzt. Insofern ist es wahrscheinlich müßig, sich darüber große Gedanken zu machen, bevor man nicht wirklich mal auf einen praktischen Fall stößt.

    Für welcher Wochentag ist heute und mach dann etwas entsprechendes ist Switch immer gut zu gebrauchen.
    Wichtig ist nur, dass das, was du ausgeben möchtest, nicht fest im Code ist.

    Zu gebrauchen z.b. für einen Terminplaner.



  • Hab noch etwas vergessen:

    Praktiker schrieb:

    Musst du nur schauen ob dein Wert einem bestimmten anderen Wert aus einer überschaubaren Menge entspricht nimmst du switch.

    Ist die Menge, mit der verglichen werden soll, nicht mehr überschaubar, dann ist weder if/else noch switch das Problem, sondern die Datenstruktur.

    Bsp:
    Wenn du wissen willst, ob ein bestimmtes Wort in einem Wörterbuch vorhanden ist, dann packst du ganz sicher nicht das ganze Wörterbuch in eine Switchanweisung.
    Und eine Kaskade von if Anweisungen machst du da auch nicht.


  • Mod

    Praktiker schrieb:

    Für welcher Wochentag ist heute und mach dann etwas entsprechendes ist Switch immer gut zu gebrauchen.
    Wichtig ist nur, dass das, was du ausgeben möchtest, nicht fest im Code ist.

    Zu gebrauchen z.b. für einen Terminplaner.

    Was möchtest du bei einem Terminplaner switchen? Ein Terminplaner ist doch ein Paradebeispiel für eine Anwendung, bei der möglichst viel dynamisch gehalten werden sollte.



  • Was möchtest du bei einem Terminplaner switchen? Ein Terminplaner ist doch ein Paradebeispiel für eine Anwendung, bei der möglichst viel dynamisch gehalten werden sollte.

    es ist doch völlig unrelevant ob die Software sehr dynamisch ist oder nicht - wenn es irgendwo viele If-Statements (z.B. in einer von mehreren fixen Statemachine gibt - die es vielleicht nicht so oft in einem Terminplaner gibt) wo nur ein State verglichen werden sollte man dafür sinnvollerweise switch verwenden



  • und es ist doch eigentlich normal Zustandskomplexität mit If-Statements auf einfache Zustände zu mappen und diesen dann mit switch-case weiter zu verarbeiten - daher verstehe ich diese If-oder-Switch-Frage und die Diskussionen hier nicht wirklich



  • SeppJ schrieb:

    Das ist ja nicht zum Aushalten! Du kapierst nicht einmal, was andere gesagt haben, aber machst dich darüber lustig. Wenn man in einem Programm an einer Stelle 50 Verzweigungen hat, ist das Problem ist nicht, dass man diese nicht als switch schreiben sollte, sondern das Problem ist dann, dass man in deinem Programm 50 Verzweigungen an einer Stelle hat!

    Versuchst du gerade, dich aus dieser Peinlichkeit herauszuwinden? Dann konfrontiere ich dich mal damit, was du TATSÄCHLICH geschrieben hast:

    SeppJ schrieb:

    Wenn du viele Bedingungen fest im Code stehen hast, machst du wahrscheinlich etwas falsch. Außerhalb von Beispielcodes habe ich jedenfalls noch nie switch benutzt.

    Und wieso sollte ich in einer State-Maschine, die 50 Zustände hat, diese 50 Zustände nicht an eine Stelle schreiben? Dann behalte ich wenigstens leicht den Überblick, welcher Zustand zu welchem Funktionsaufruf führt.

    Wenn diese States sich nicht logisch gruppieren lassen, macht es keinen Sinn, sie künstlich zu zerhacken - und kostet im Falle einer sinnlosen Aufpslittung sogar noch zusätzlich Rechenzeit.


  • Mod

    Gast3 schrieb:

    Was möchtest du bei einem Terminplaner switchen? Ein Terminplaner ist doch ein Paradebeispiel für eine Anwendung, bei der möglichst viel dynamisch gehalten werden sollte.

    es ist doch völlig unrelevant ob die Software sehr dynamisch ist oder nicht - wenn es irgendwo viele If-Statements (z.B. in einer von mehreren fixen Statemachine gibt - die es vielleicht nicht so oft in einem Terminplaner gibt) wo nur ein State verglichen werden sollte man dafür sinnvollerweise switch verwenden

    Wenn die Logik dynamisch ist (oder sehr komplex, was bedeutet, dass man ernsthaft in Betracht ziehen sollte, sie dynamisch zu machen), dann würde das ganze halt durch Lookups in passende Datenstrukturen erfolgen, anstatt durch fest-codierte Anweisungen in der Programmlogik. Macht effektiv das gleiche (ein Arrayzugriff und ein Jumptable tun sich nicht viel), hält aber den Code einfacher und flexibler.



  • Gast3 schrieb:

    und es ist doch eigentlich normal Zustandskomplexität mit If-Statements auf einfache Zustände zu mappen und diesen dann mit switch-case weiter zu verarbeiten - daher verstehe ich diese If-oder-Switch-Frage und die Diskussionen hier nicht wirklich

    Dann lies' mal das Ursprungsposting. Es geht um Rechenzeiteinsparung.

    Fakt ist, dass ein Ablauf

    if (bedingung)
    {
    }
    else if (bedingung)
    {
    }
    else if (bedingung)
    {
    }
    else if (bedingung)
    {
    }
    

    um so mehr Zeit benötigt, um so weiter unten die erfüllte Bedingung steht - schlicht weil de CPU jede Bedingung einzeln überprüfen muss.

    Deswegen wurde ja switch-case eingeführt, welches sofort auf den passenden Wert springt. "bedingung" muss hier logischerweise ein Vergleich auf Gleichheit sein, sonst lässt sich switch-case nicht verwenden.

    Das Problem: switch-case hat per se erst mal ein wenig Overhead, weil es mit irgend welchen lustigen Jumptables arbeitet.

    Die eigentliche Frage war hier, ab wie vielen if-else-Kaskadierungen sich ein Ersetzen durch switch-case lohnt, weil dann diese Jumptables effektiver sind, als für einen Durchlauf bis zur letzten Bedingung.

    Nur scheint das eine Frage zu sein, die in diesem Forum noch nicht mal verstanden wird, geschweige denn zu der eine brauchbare Antwort möglich ist.

    Statt dessen glänzt hier ein "Supermoderator" mit geradezu peinlichen Aussagen, vo denen man ernsthaft warnen sollte.



  • @SeppJ

    Wenn die Logik dynamisch ist (oder sehr komplex, was bedeutet, dass man ernsthaft in Betracht ziehen sollte, sie dynamisch zu machen), dann würde das ganze halt durch Lookups in passende Datenstrukturen erfolgen, anstatt durch fest-codierte Anweisungen in der Programmlogik. Macht effektiv das gleiche (ein Arrayzugriff und ein Jumptable tun sich nicht viel), hält aber den Code einfacher und flexibler.

    wieso veränderst du den Kontext der Ursprungsfrage?
    es ging hier nirgends um komplexe dynamische Fallunterscheidungen - die man wo ich dir recht geben lieber anders lösen sollte - aber das war hier einfach nicht die Frage - und wenn du hohe Verarbeitungsraten fährst ist "(ein Arrayzugriff und ein Jumptable tun sich nicht viel)" ziemlich weit aus dem Fenster gelehnt - wir kennen doch gar nicht den Kontext - 1ms Echtzeit, 10 Mio Datenpakete in 10ms, und und und - klar ist es nur wenn man genau dein Beispiel von einem einfachen dynamischen Terminplaner nimmt - mit den Features die nur du kennst und dann damit argumentiert



  • So, damit sich hier nicht noch mehr Unwissenheit, Halbwahrheiten und Gerüchte verbreiten, lasse ich mal an meinen Erkennissen aus anderen Foren teilhaben: die alte switch-case-Geschwindigkeitsregel ist hinfällig.

    Tatsächlich schauen sich (gute) moderne Compiler die verwendeten Werte an und machen aus einem switch-case - wenn sinnvoll - schon mal das Äquivalent einer if-else-Kette. Oder eine Jumptable. Oder einen binären Abfragebaum. Oder was an der Stelle sonst sinvoll ist.

    Die daraus abzuleitende Regel wäre eher, switch-case immer dann zu verwenden, wenn es übersichtlicher wird, also IMHO so ab drei Abfragen.


  • Mod

    Gast3 schrieb:

    wieso veränderst du den Kontext der Ursprungsfrage?

    Was ist denn die Ursprungsfrage? Ob man switch in der Praxis oft (oder überhaupt) braucht? Das war jedenfalls die Frage, die ich dir beantworten wollte. Dass ich bewusst nicht auf Tomots Unsinn eingehe, habe ich bereits klar gemacht.


  • Mod

    Tomot schrieb:

    Tatsächlich schauen sich (gute) moderne Compiler die verwendeten Werte an und machen aus einem switch-case - wenn sinnvoll - schon mal das Äquivalent einer if-else-Kette. Oder eine Jumptable. Oder einen binären Abfragebaum. Oder was an der Stelle sonst sinvoll ist.

    Erste Antwort hier in diesem ach so inkompetenten Forum:

    afdasfd schrieb:

    oO

    Erinnerungen mögen trügen. Im Grunde sollte es egal sein. Der Compiler dürfte das zum gleichen Code verhackstücken.

    Du kannst ja mal zum Test dem Compiler deiner Wahl sagen, dass er den Assembler Code ausspucken soll. Dort kannst du dann schön vergleichen.



  • SeppJ schrieb:

    Erste Antwort hier in diesem ach so inkompetenten Forum:

    Dir muss man echt lesen helfen, oder? Diese Antwort beschreibt, dass ein if-else auch mal in ein switch-case-Äquivalent umgewandelt wird.

    Davon habe ich aber NICHTS geschrieben! Es scheint nur das Gegenteil der Fall zu sein, dass ein switch-case auch mal zu einem if-else-Äquivalent (oder eben zu ganz was anderem) umgewandelt wird.

    Und dass if-else nicht zwangsläufig zum gleichen Code wie switch-case wird, kann man unter gcc.godbolt.org ganz leicht überprüfen.



  • Unregistrierte sind mir sowieso suspekt.
    SeppJ ist ein hochanständiger und wissender Mensch, ihr kleinen Schei**haufen da außen.



  • SeppJ schrieb:

    Praktiker schrieb:

    Für welcher Wochentag ist heute und mach dann etwas entsprechendes ist Switch immer gut zu gebrauchen.
    Wichtig ist nur, dass das, was du ausgeben möchtest, nicht fest im Code ist.

    Zu gebrauchen z.b. für einen Terminplaner.

    Was möchtest du bei einem Terminplaner switchen? Ein Terminplaner ist doch ein Paradebeispiel für eine Anwendung, bei der möglichst viel dynamisch gehalten werden sollte.

    Z.B. welcber Tag ist heute?

    Dinge die du regelmäßig machst, sind sicherlich an einem bestimmten Wochentag, also wird da nach dem Wochentag geswitched.
    Und was an dem Wochentag stattfindet, das entnimmst du dann der Datenstruktur.



  • Lange switch-Statements würde ich fast immer durch eine Lookup-Table ersetzen. Ganz egal welcher micro-optimierte Code hinten rauskommt.

    Wenn ich mir den "Clean Code"-Hut aufsetze, dann muss ich auch SeppJ voll recht geben, aber es mag natürlich Einzelfälle geben in denen ein großes switch oder eine if/else-Tirade tatsächlich Sinn machen könnte...aber man sollte auf jeden Fall mal aufmerksam werden. Alarmglocken sollten aufleuchten.

    MfG SideWinder



  • Z.B. welcber Tag ist heute?

    calendar.today()? Oder meinst du für die Ausgabe? Dann wohl eher sowas in die Richtung I18N.WeekDays[calender.dayoftheweek()]. switch/if erscheint mir falsch.

    MfG SideWinder



  • [quote="Tomot"]
    Fakt ist, dass ein Ablauf

    if (bedingung)
    {
    }
    else if (bedingung)
    {
    }
    else if (bedingung)
    {
    }
    else if (bedingung)
    {
    }
    

    um so mehr Zeit benötigt, um so weiter unten die erfüllte Bedingung steht - schlicht weil de CPU jede Bedingung einzeln überprüfen muss.
    [QUOTE]

    So würde man nicht programmieren.

    Wenn man schon if nimmt, dann würde man hier die Bedingungen in Gruppen zusammenfassen und nach diesen verschachteln und erst in der eingebetten if Bedingung genauer abfragen.

    Einfaches Beispiel.
    Buchstaben A-Z, welcher wurde eingegeben?

    if (eingabe <= 'M'){
      if (eingabe <= 'F'){
         /* und nun einzeln detailiert, wobei es sich hier danns schon lohnt switch zu nehmen, aber im Grunde würde wäre es wohl am schnellsten, wenn man für A-Z ein switch verwendet, mir ging es jetzt aber nur um mal kurz etwas zu veranschaulichen und ein besseres Beispiel ist mir nicht eingefallen */
      } else {
         // behandelt G-M
      }
    else {
      if (eingabe <= 'S'{
        // ... wie siehe oben, behandelt N-S
      } else {
        // behandelt T-Z
      }
    
    }
    

    Das Problem: switch-case hat per se erst mal ein wenig Overhead, weil es mit irgend welchen lustigen Jumptables arbeitet.

    Die eigentliche Frage war hier, ab wie vielen if-else-Kaskadierungen sich ein Ersetzen durch switch-case lohnt, weil dann diese Jumptables effektiver sind, als für einen Durchlauf bis zur letzten Bedingung.

    Ich würde sagen, das hängt von Fall zu Fall und von Compiler zu Compiler ab.
    Du wirst es testen und vergleichen müssen.
    Dazu Vergleiche von Strings sind sicherlich aufwendiger als reine Zahlenwerte.
    Man muss sich also in die Assemblersicht versetzten und überlegen, wie man das optimieren könnte, also wie es der Compiler optimieren würde.



  • SideWinder schrieb:

    Z.B. welcber Tag ist heute?

    calendar.today()? Oder meinst du für die Ausgabe? Dann wohl eher sowas in die Richtung I18N.WeekDays[calender.dayoftheweek()]. switch/if erscheint mir falsch.

    MfG SideWinder

    Und das hast du alles in einem µC?
    Also ne fette lib?


Anmelden zum Antworten