it-swarm.com.de

Ternärer Operator?: Vs if ... else

Ist der Operator?: In C++ schneller als if () ... else-Anweisungen? Gibt es Unterschiede in kompiliertem Code?

63
Xirdus

Abhängig von Ihrem Compiler, aber bei jedem modernen Compiler gibt es normalerweise keinen Unterschied. Es ist etwas, worüber Sie sich keine Sorgen machen sollten. Konzentrieren Sie sich auf die Wartbarkeit Ihres Codes.

81
ptomato

Es geht nicht schneller. Es gibt einen Unterschied, wenn Sie eine konstante Variable abhängig von einem Ausdruck initialisieren können:

const int x = (a<b) ? b : a;

Mit if-else können Sie nicht dasselbe tun.

91

Ich habe gesehen, wie GCC den Bedingungsoperator in cmov (bedingte Verschiebungs-) Anweisungen umwandelte, während if-Anweisungen in Verzweigungen umgewandelt wurden, was in unserem Fall bedeutete, dass der Code bei Verwendung des Bedingungsoperators schneller war. Aber das war vor ein paar Jahren und wahrscheinlich heute würden beide zum selben Code kompilieren.

Es gibt keine Garantie, dass sie nach demselben Code kompilieren. Wenn Sie die Leistung benötigen, dann wie immer measure . Und wenn Sie gemessen und herausgefunden haben, dass 1. Ihr Code zu langsam ist und 2. es sich hierbei um diesen bestimmten Codeabschnitt handelt, sollten Sie den vom Compiler generierten Assembly-Code studieren und sich selbst überlegen, was passiert.

Vertrauen Sie nicht auf goldene Regeln wie "der Compiler erzeugt immer effizienteren Code, wenn ich den Bedingungsoperator verwende".

40
jalf

Sie sind gleich, der ternäre Operator kann jedoch an Orten verwendet werden, an denen es schwierig ist, ein if/else zu verwenden:

printf("Total: %d item%s", cnt, cnt != 1 ? "s" : "");

Wenn Sie diese Anweisung mit einem if/else ausführen, wird ein sehr anderer kompilierter Code generiert.


Update nach 8 Jahren ...

Eigentlich denke ich, dass das besser wäre:

printf(cnt == 1 ? "Total: %d item" : "Total: %d items", cnt);

(Ich bin mir ziemlich sicher, dass Sie "% d" in der ersten Zeichenfolge durch "Eins" ersetzen können.)

14
James Curran

Nur um ein bisschen Linkshänder zu sein ...

x ? y : x = value

wird value zu y zuweisen, wenn x nicht 0 ist (false).

2
VS3

Ungeachtet des kompilierten Codes sind sie semantisch etwas anderes. <cond>?<true expr>:<false expr> ist ein Ausdruck und if..else.. ist eine Anweisung.

Obwohl die Syntax des bedingten Ausdrucks unangenehm erscheint, ist es eine gute Sache. Sie müssen einen <false expr> angeben, und die beiden Ausdrücke werden vom Typ geprüft.

Das Äquivalent zu if..else.. in ausdrucksbasierter, funktionaler Sprache wie LISP ist Haskell ? : in C++ anstelle von if..else..-Anweisung.

2
amdyes

Der ternäre Operator gibt immer einen Wert zurück. Wenn also ein Ausgabewert vom Ergebnis gewünscht wird und es nur zwei Bedingungen gibt, ist es besser, den ternären Operator zu verwenden wahr.

0
Raheel Afzal

Jetzt kann ich Ihnen nicht helfen, ich kann vielleicht mit einer sekundären Frage darunter helfen, möchte ich sie verwenden? Wenn Sie nur von der Geschwindigkeit wissen möchten, ignorieren Sie einfach meinen Kommentar.

Alles, was ich sagen kann, ist bitte sehr klug zu sein, wann man das Ternary benutzt. : Operator. Es kann ein Segen sein wie ein Fluch für die Lesbarkeit. 

Fragen Sie sich, ob Sie das Lesen leichter finden, bevor Sie es verwenden

int x = x == 1 ? x = 1 : x = 1;

if (x == 1)
{
   x = 1
}
else
{
   x = 2
}

if (x == 1)
    x = 1
else
    x = 1

Ja, es sieht dumm aus, den Code zu 100% falsch zu machen. Dieser kleine Trick half mir jedoch, meine Lesbarkeit von Code zu analysieren. Es ist die Lesbarkeit des Operators, den Sie in diesem Beispiel betrachten, und nicht der Inhalt. 

Es sieht sauber aus, aber auch der durchschnittliche Toilettensitz und der Türknopf

Nach meiner Erfahrung, die begrenzt ist, habe ich gesehen, dass sehr wenige Menschen in der Lage waren, schnell die erforderlichen Informationen von einem ternären Betreiber auszuliefern. Es ist ein Schmerz, der behoben werden muss, wenn es abgehört wird, denke ich

0
Proclyon

Sie sind nicht gezwungen, alles auf eine Zeile zu setzen: -

x = y==1 ?
    2
    :// else
    3;

Es ist viel klarer als wenn/sonst, weil Sie sofort sehen können, dass beide Zweige dazu führen, dass x zugewiesen wird.

0
QuentinUK

Ich würde erwarten, dass es auf den meisten Compilern und Zielplattformen Fälle gibt, in denen "wenn" schneller ist und Fälle, in denen?: Schneller ist. Es gibt auch Fälle, in denen eine Form mehr oder weniger kompakt ist als die andere. Welche Fälle die eine oder die andere Form bevorzugen, variiert je nach Compiler und Plattform. Wenn Sie auf einem Embedded Micro leistungskritischen Code schreiben, schauen Sie sich an, was der Compiler jeweils generiert, und sehen Sie, was besser ist. Auf einem "Mainstream" -PC kann man aufgrund von Caching-Problemen nur feststellen, welche der beiden Methoden besser ist, wenn man beide Formen in einem Vergleich mit der realen Anwendung vergleicht.

0
supercat

In C Ein ternärer Operator "?:" Ist verfügbar, um bedingte Ausdrücke des Formulars zu konstruieren

exp1 ? exp2:exp3

dabei sind exp1, exp2 und exp3 Ausdrücke

zum Beispiel

        a=20;
        b=25;
        x=(a>b)?a:b;

        in the above example x value will be assigned to b;

Dies kann mit der Anweisung if..else wie folgt geschrieben werden

            if (a>b)
             x=a;
             else
             x=b;

** Daher gibt es keinen Unterschied zwischen diesen beiden. Dies ist für den Programmierer einfach zu schreiben, aber für den Compiler sind beide gleich. *

0
ksrao

Ich denke, dass es Situationen gibt, in denen die Inline-Funktion aufgrund ihres Umfangs einen "schnelleren" Code liefern kann. Die Erstellung und Zerstörung von Objekten kann kostspielig sein. Beachten Sie das folgende Szenario:

class A{
    public:
    A() : value(0) {
        cout << "Default ctor" << endl;
    }
    A(int myInt) : value(myInt)
    {
        cout << "Overloaded ctor" << endl;
    }

    A& operator=(const A& other){
        cout << "= operator" << endl;
        value = other.value; 
    }

    ~A(){
        cout << "destroyed" << std::endl;
    }

    int value;

};


int main()
{
   {
       A a;
       if(true){
           a = A(5);
       }else{
           a = A(10);
       }
   }

   cout << "Next test" << endl;
   {
        A b = true? A(5) : A(10);
   }
   return 0;
}

Mit diesem Code lautet die Ausgabe:

Default ctor                                                                                                                                                                                                                      
Overloaded ctor                                                                                                                                                                                                                   
= operator                                                                                                                                                                                                                        
destroyed                                                                                                                                                                                                                         
destroyed                                                                                                                                                                                                                         
Next test                                                                                                                                                                                                                         
Overloaded ctor                                                                                                                                                                                                                   
destroyed  

Indem wir das if inlinen, speichern wir eine Reihe von Operationen, die erforderlich sind, um a im selben Bereich wie b am Leben zu erhalten. Obwohl es sehr wahrscheinlich ist, dass die Zustandsbewertungsgeschwindigkeit in beiden Szenarien ziemlich gleich ist, müssen Sie bei einer Änderung des Gültigkeitsbereichs andere Faktoren berücksichtigen, die durch die Inline-Funktion vermieden werden. 

0
Eric

Während des Umkehrens eines Codes (an den ich mich vor einigen Jahren nicht erinnere) habe ich einen einzelnen Zeilenunterschied zwischen dem Maschinencode von: und if-else .Don't remember much but it is clear that implementation of both is different.

Aber ich empfehle Ihnen, keinen von ihnen aus Effizienz zu wählen, je nach Lesbarkeit des Codes oder Ihrer Bequemlichkeit . Happy Coding

0
Pervez Alam