Éditer:
Ajout d'un exemple qui peut être fait avec l'instruction if-else mais pas l'opérateur conditionnel.
Avant la réponse, veuillez jeter un œil à [ Quel est le plus rapide? ] sur le blog de M. Lippert. Et je pense que la réponse de M. Ersönmez est la plus juste ici.
J'essaie de mentionner quelque chose que nous devons garder à l'esprit avec un langage de programmation de haut niveau.
Tout d'abord, je n'ai jamais entendu dire que l'opérateur conditionnel est censé être plus rapide ou la même performance avec l'instruction if-else en C♯ .
La raison est simple: que faire s'il n'y a pas d'opération avec l'instruction if-else:
if (i > 0)
{
value += 2;
}
else
{
}
L'exigence de l'opérateur conditionnel est qu'il doit y avoir une valeur de chaque côté, et en C♯, il faut également que les deux côtés de :
aient le même type. Cela le rend juste différent de l'instruction if-else. Ainsi, votre question devient une question demandant comment l'instruction du code machine est générée pour que la différence de performance.
Avec l'opérateur conditionnel, sémantiquement c'est:
Quelle que soit l'expression évaluée, il y a une valeur.
Mais avec l'instruction if-else:
Si l'expression est évaluée à true, faites quelque chose; sinon, faites autre chose.
Une valeur n'est pas nécessairement impliquée dans l'instruction if-else. Votre hypothèse n'est possible qu'avec l'optimisation.
Un autre exemple pour démontrer la différence entre eux serait le suivant:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
if(i>0)
array1[1]=4;
else
array2[2]=4;
le code ci-dessus compile, cependant, remplace l'instruction if-else par l'opérateur conditionnel ne compilera tout simplement pas:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
(i>0?array1[1]:array2[2])=4; // incorrect usage
L'opérateur conditionnel et les instructions if-else sont conceptuellement les mêmes lorsque vous faites la même chose, cela peut même être plus rapide avec l'opérateur conditionnel en C , car C est plus proche de l'assemblage de la plate-forme.
Pour le code d'origine que vous avez fourni, l'opérateur conditionnel est utilisé dans une boucle foreach, ce qui gâcherait les choses pour voir la différence entre eux. Je propose donc le code suivant:
public static class TestClass {
public static void TestConditionalOperator(int i) {
long value=0;
value+=i>0?2:3;
}
public static void TestIfElse(int i) {
long value=0;
if(i>0) {
value+=2;
}
else {
value+=3;
}
}
public static void TestMethod() {
TestConditionalOperator(0);
TestIfElse(0);
}
}
et ce qui suit sont deux versions de l'IL optimisé et non. Puisqu'ils sont longs, j'utilise une image pour montrer, le côté droit est optimisé:
(Cliquez pour voir l'image en taille réelle.)
Dans les deux versions de code, l'IL de l'opérateur conditionnel semble plus court que l'instruction if-else, et il existe toujours un doute sur le code machine finalement généré. Voici les instructions des deux méthodes, et l'ancienne image n'est pas optimisée, la dernière est optimisée:
Dans ce dernier, le bloc jaune est le code exécuté uniquement si i<=0
, et le bloc bleu est quand i>0
. Dans l'une ou l'autre version des instructions, l'instruction if-else est plus courte.
Notez que, pour des instructions différentes, le [ CPI ] n'est pas nécessairement le même. Logiquement, pour une instruction identique, plus d'instructions coûtent un cycle plus long. Mais si le temps de récupération des instructions et le canal / cache étaient également pris en compte, le temps total réel d'exécution dépend du processeur. Le processeur peut également prédire les branches.
Les processeurs modernes ont encore plus de cœurs, les choses peuvent être plus complexes avec cela. Si vous étiez un utilisateur de processeur Intel, vous voudrez peut-être consulter le [ Manuel de référence de l'optimisation des architectures Intel® 64 et IA-32 ].
Je ne sais pas s'il y avait un CLR implémenté par le matériel, mais si oui, vous obtenez probablement plus rapidement avec l'opérateur conditionnel car l'IL est évidemment moindre.
Remarque: Tous les codes machine sont de x86.
DateTime
pour mesurer les performances. UtilisezStopwatch
. Ensuite, le temps est plus long - c'est un temps très court pour mesurer.