Performance des ?-Operators
-
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