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é?
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.
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
.
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".
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")
Juste pour être un peu gaucher...
x ? y : x = value
Attribuera valeur à y si x n'est pas 0 (false).
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..
.
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
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.
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
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.
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.
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.
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.*
Non, ils sont convertis en exactement le même code exécutable.