Performance des ?-Operators



  • Hallo,

    habe gerade überlegt, ob der ?-Operator intern schneller ist, als die Verwendung von if...else!?

    Gibt es da irgendwelche (performance-technisch gesehen) Unterschiede? Oder ist das nur eine syntaktische Vereinfachung und dient eventuell somit nur der Lesbarkeit (sofern nicht x-mal ineinander verschachtelt)?

    Beispiel:

    int check = 1;
    
    return( !( check = funktion() ) ? 1 : 0 );
    
    /* oder halt if-else ... */
    if( !( check = funktion() ) )
       return 1;
    
    else
       return 0;
    

    Grüße hando



  • Technisch gesehen sollte das keinen großen Unterschied machen - aber womöglich bietet der ?:-Operator ganz andere Optimierungsmöglichkeiten als ein if-else.

    (PS: Dir ist hoffentlich klar, daß Vergleiche per == durchgeführt werden)



  • CStoll schrieb:

    Technisch gesehen sollte das keinen großen Unterschied machen - aber womöglich bietet der ?:-Operator ganz andere Optimierungsmöglichkeiten als ein if-else.

    (PS: Dir ist hoffentlich klar, daß Vergleiche per == durchgeführt werden)

    Ähem ... ja schon klar, dass Vergleich mit dem ==-Operator durchgeführt werden, nur bekommt ja hier check den Wert aus irgendeiner Funktion zugewiesen.



  • hallo

    Warum nimmst du dann nicht direkt die Funktion?

    chrische



  • Also bei mir ergibt folgender Test:

    {
        DSTOPWATCH("ifelse");
        int y;
        for ( double x=0; x<400000000; x++ )
        {
            if ( x>=1000 )
                y=1;
            else 
                y=x;
        }
    }
    
    {
        DSTOPWATCH("?");
    
        int y;
        for ( double x=0; x<400000000; x++ )
        {
            y=x>=1000?1:x;
        }
    }
    

    dass beide Schleifen auf meinem Rechner 672 Takte brauchen.



  • hando schrieb:

    Ähem ... ja schon klar, dass Vergleich mit dem ==-Operator durchgeführt werden, nur bekommt ja hier check den Wert aus irgendeiner Funktion zugewiesen.

    Und wozu soll das an der Stelle gut sein? mit dem 'return' verlässt du die Funktion und damit fliegt check sowieso aus dem Scope.

    @vixVerge: Es wäre nett, zu beiden Varianten den erzeugten Assambler-Code zu sehen 😉



  • @chrische5 und CStoll:
    Es war nur ein dummes Beispiel ohne irgendwelche relevanten Bezüge auf irgendein Programm - vielleicht etwas unglücklich gewählt das Beispiel ... ja 🙂



  • CStoll schrieb:

    aber womöglich bietet der ?:-Operator ganz andere Optimierungsmöglichkeiten als ein if-else.

    Hast da was spezielles im Sinn? Mir will grad nichts einfallen, was bei ?: besser optimiert werden könnte. Liegt vielleicht auch daran, dass ich ihn einfach nicht mag 😉



  • Vor allem ist die ?:-Konstruktion ein Ausdruck und kann damit auch in größeren Zusammenhängen verwendet werden (if-else ist kein Ausdruck) - zum Beispiel als Teilausdruck in einer größeren Anweisung val = func()*(pos?1:-1); oder in der Argumentliste einer Funktion.



  • für

    if ( x>3 )
        y=0;
    else
        y=255;
    

    wäre das

    cmp	DWORD PTR _x$[ebp], 3
        jle	SHORT $L269
        mov	DWORD PTR _y$[ebp], 0
        jmp	SHORT $L270
    $L269:
        mov	DWORD PTR _y$[ebp], 255
    $L270:
    

    für

    y = x>3?0:255;
    
    xor	eax, eax
        cmp	DWORD PTR _x$[ebp], 3
        setle	al
        dec	eax
        and	al, 1
        add	eax, 255				; 000000ffH
        mov	DWORD PTR _y$[ebp], eax
    


  • Function: __X_f1
       88:  void f1 (void) 
       89:  {
       81:    volatile int x, y;
       82:    if (x > 3)
      0000 c203             SUBL       R2,#3
      0002 3a01             BLE        L6
       83:      y = 0;
      0004 06f6             JAL        R6
      0006          L6:     
       84:    else
       85:      y = 255;
      0006 f2ff             LDL        R2,#255
       86:  }
      0008 06f6             JAL        R6
       87:  
    
    Function: __X_f2
       88:  void f2 (void) 
       89:  {
       90:    volatile int x, y;
       91:    y = x > 3 ? 0: 255;
      0000 c203             SUBL       R2,#3
      0002 3801             BGT        L6
      0004 06f6             JAL        R6
      0006          L6:     
      0006 1202             MOV        R2,R0
       92:  }
      0008 06f6             JAL        R6
       93:
    


  • ^^ RISC?



  • In Sachen Performance unterscheiden sich beide Varianten je nach Implementierung wenn überhaupt nur geringfügig. Dieser Unterschied ist anscheinend so gering das er eine Applikation nicht relevant einschränkt. Ferner sollte man sich in Anbetracht der immer leistungsstärker werdenden Hardware nicht zu viele Gedanken bezüglich Schnelligkeit des resultierenden Programms machen.

    Ich schätze an dieser Stelle Lesbarkeit und Ästhetik des Quelltextes deutlich wichtiger ein. Zu bedenken ist, dass beide Alternativen (Schlüsselwörter if...else und der Operator ? : ) unterschiedliche Anwendungsfälle besitzen.

    Das if...else-Konstrukt wird als Teil der strukturierten Programmierung eingeordnet (ist ferner also auch in Paradigmen, welche auf das strukturierte basieren, enthalten) und wird für die Steuerung des Ablaufs einer Routine verwendet. if und else sind Schlüsselwörter aus C/C++!

    Der Operator ?: dient der Verwendung in Ausdrücken, also wie bereits erwähnt in Rückgabewerten, Initialisierungslisten oder bei der Zuweisung eines Wertes an eine Variable.

    // Verzweigung als Strukturelement
    if (f())
      g();
    else
      h();
    
    // Verzweigung in Ausdrücken
    return f() ? 1 : -1;
    
    // "Missbrauch" des Operators
    f() ?
      g()
    :
      h();
    
    /* Der Rückgabewert des Operators wird nicht verwendet bzw. "verworfen";
    die Möglichkeit mit if...else zu arbeiten ist vorzuziehen. */
    

    Grüße
    Martin


Anmelden zum Antworten