Opérateur ternaire: vs if ... else

En c++, est le?: opérateur plus rapidement que si()...else? Existe-il des différences entre eux dans le code compilé?

61
demandé sur Thomas Padron-McCarthy 2010-08-25 15:34:12

14 réponses

Dépend de votre compilateur, mais sur tout compilateur moderne, il n'y a généralement pas de différence. C'est quelque chose dont vous ne devriez pas vous inquiéter. Concentrez-vous sur la maintenabilité de votre code.

80
répondu ptomato 2010-08-25 11:35:16

Ce n'est pas plus rapide. Il y a une différence lorsque vous pouvez initialiser une variable constante en fonction d'une expression:

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

Vous ne pouvez pas faire la même chose avec if-else.

90
répondu Kirill V. Lyadvinsky 2010-08-25 11:36:28

J'ai vu GCC transformer l'opérateur conditionnel en instructions cmov (mouvement conditionnel), tout en transformant les instructions if en branches, ce qui signifiait dans notre cas, que le code était plus rapide lors de l'utilisation de l'opérateur conditionnel. Mais c'était il y a quelques années, et très probablement, aujourd'hui, serait de compiler le même code.

Il n'y a aucune garantie qu'ils compileront le même code. Si vous avez besoin de la performance, alors, comme toujours, mesure . Et quand vous avez mesuré et découvert que 1. votre code est trop lent, et 2. c'est ce morceau de code qui est le coupable, puis étudier le code assembleur généré par le compilateur et vérifiez par vous-même ce qui se passe.

Ne faites pas confiance aux règles d'or comme "le compilateur générera toujours du code plus efficace si j'utilise l'opérateur conditionnel".

39
répondu jalf 2010-08-26 00:27:56

Ils sont les mêmes, cependant, l'opérateur ternaire peut être utilisé dans des endroits où il est difficile d'utiliser un if/else:

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

Faire cette instruction avec un if / else, générerait un code compilé très différent.


Mise à jour après 8 ans...

En Fait, je pense que ce serait mieux:

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

(en fait, je suis sûr que vous pouvez remplacer le "%d" dans la première chaîne par "one")

13
répondu James Curran 2018-09-05 01:42:50

Juste pour être un peu gaucher...

x ? y : x = value

Attribuera valeur à y si x n'est pas 0 (false).

3
répondu VS3 2014-07-15 19:27:46

Quel que soit le code compilé, ils sont sémantiquement différents. <cond>?<true expr>:<false expr> est une expression et if..else.. est une instruction.

Bien que la syntaxe de l'expression conditionnelle semble maladroite, c'est une bonne chose. Vous êtes obligé de fournir un <false expr> et les deux expressions sont vérifiées.

L'équivalent de if..else.. dans un langage fonctionnel basé sur l'expression comme Lisp, Haskell est ? : en C++, au lieu de l'instruction if..else...

2
répondu Fu Wenhui 2015-12-23 02:53:30

Maintenant, je ne peux pas vous aider, je peut être en mesure d'aider avec une question secondaire-dessous d'elle, veux-je l'utiliser? Si vous voulez juste connaître la vitesse, ignorez simplement mon commentaire.

Tout ce que je peux dire, c'est être très intelligent sur le moment d'utiliser le ternaire ? : opérateur. Cela peut être une bénédiction autant qu'une malédiction pour la lisibilité.

Demandez-vous si vous trouvez cela plus facile à lire avant de l'utiliser

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

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

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

Oui, il semble stupide de rendre le code 100% faux. Mais ce petit tour m'a aidé à analyser ma lisibilité du code. C'est la lisibilité de l'opérateur que vous regardez dans cet exemple, et non le contenu.

Il semble propre, mais le siège de toilette moyen et la poignée de porte aussi

Dans mon expérience, qui est limitée, j'ai vu très peu de gens être en mesure d'extrader rapidement les informations requises d'un opérateur ternaire, éviter à moins que 100% sûr que c'est mieux. C'est une douleur à réparer quand il est aussi buggé je pense

0
répondu Proclyon 2010-08-25 12:06:06

Je m'attendrais à ce que sur la plupart des compilateurs et des plates-formes cibles, il y aura des cas où "si" est plus rapide et des cas où ?: est plus rapide. Il y aura aussi des cas où une forme est plus ou moins compacte que l'autre. Les cas qui favorisent une forme ou l'autre varieront entre les compilateurs et les plates-formes. Si vous écrivez du code critique pour les performances sur un micro intégré, regardez ce que le compilateur génère dans chaque cas et voyez lequel est le meilleur. Sur un PC "grand public", en raison de problèmes de mise en cache, la seule façon de voir ce qui est mieux est de comparer les deux formes dans quelque chose qui ressemble à l'application réelle.

0
répondu supercat 2010-08-25 15:21:01

Pendant l'inversion du code (dont je ne me souviens pas, il y a quelques années), j'ai vu une seule ligne de différence entre le Code Machine de:? et if-else. Don't remember much but it is clear that implementation of both is different.

Mais je vous conseille de ne pas choisir l'un d'entre eux b'coz de son efficacité, choisissez selon la lisibilité du code ou votre convenance. Code Heureux

0
répondu Pervez Alam 2012-01-19 12:42:50

L'opérateur ternaire renvoie toujours une valeur. Donc, dans la situation où vous voulez une valeur de sortie du résultat et il n'y a que 2 conditions toujours préférable d'utiliser l'opérateur ternaire. Utilisez if-else si l'une des conditions mentionnées ci-dessus n'est pas vraie.

0
répondu Raheel Afzal 2012-02-07 16:58:16

Je pense qu'il y a des situations où l'inline if peut donner du code "plus rapide" en raison de la portée à laquelle il fonctionne. La création et la destruction d'objets peuvent être coûteuses, alors considérez le scénario suivant:

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;
}

, Avec ce code, la sortie sera :

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

Donc, en insérant le if, nous enregistrons un tas d'opérations nécessaires pour garder a en vie dans la même portée que b. Bien qu'il soit très probable que la vitesse d'évaluation de la condition soit assez égale dans les deux scénarios, la portée changeante vous oblige à prendre en compte d'autres facteurs que la ligne si vous permet de l'éviter.

0
répondu Eric 2015-06-04 23:10:20

Vous n'êtes pas obligés de tout mettre sur une seule ligne:-

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

C'est beaucoup plus clair que if / else parce que vous pouvez voir immédiatement que les deux branches conduisent à l'affectation de x.

0
répondu QuentinUK 2015-11-20 00:30:01

En C un opérateur ternaire"? : "est disponible pour construire des expressions conditionnelles de la forme

exp1 ? exp2:exp3

Où exp1, exp2 et exp3 sont des expressions

Par Exemple

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

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

Cela peut être écrit en utilisant if..else déclaration comme suit

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

**par conséquent, il n'y a pas de différence entre ces deux. Ceci pour que le programmeur écrive facilement, mais pour le compilateur les deux sont les mêmes.*

-1
répondu ksrao 2010-08-25 17:28:31

Non, ils sont convertis en exactement le même code exécutable.

-3
répondu Alex F 2010-08-25 11:35:22