Editar:
Adicionado um exemplo que pode ser feito com a instrução if-else, mas não com o operador condicional.
Antes da resposta, consulte [O que é mais rápido? ] no blog do Sr. Lippert. E acho que a resposta do Sr. Ersönmez é a mais correta aqui.
Estou tentando mencionar algo que devemos ter em mente com uma linguagem de programação de alto nível.
Primeiro, nunca ouvi dizer que o operador condicional deveria ser mais rápido ou ter o mesmo desempenho da instrução if-else em C♯ .
O motivo é simples: e se não houver operação com a instrução if-else:
if (i > 0)
{
value += 2;
}
else
{
}
O requisito do operador condicional é que deve haver um valor para ambos os lados e, em C♯, também exige que ambos os lados :
tenham o mesmo tipo. Isso apenas o torna diferente da instrução if-else. Assim, sua pergunta se torna uma pergunta perguntando como a instrução do código da máquina é gerada para que a diferença de desempenho.
Com o operador condicional, semanticamente é:
Qualquer que seja a expressão avaliada, há um valor.
Mas com a declaração if-else:
Se a expressão for avaliada como verdadeira, faça algo; caso contrário, faça outra coisa.
Um valor não está necessariamente envolvido com a instrução if-else. Sua suposição só é possível com a otimização.
Outro exemplo para demonstrar a diferença entre eles seria o seguinte:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
if(i>0)
array1[1]=4;
else
array2[2]=4;
o código acima compila, no entanto, substitua a instrução if-else pelo operador condicional, que não compila:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
(i>0?array1[1]:array2[2])=4; // incorrect usage
O operador condicional e as instruções if-else são conceituais da mesma forma quando você faz a mesma coisa, possivelmente ainda mais rápido com o operador condicional em C , pois C está mais próximo da montagem da plataforma.
Para o código original que você forneceu, o operador condicional é usado em um loop foreach, o que atrapalha as coisas para ver a diferença entre eles. Então, estou propondo o seguinte código:
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);
}
}
e a seguir estão duas versões do IL de otimizado e não. Como eles são longos, estou usando uma imagem para mostrar, o lado direito é o otimizado:
(Clique para ver a imagem em tamanho real.)
Nas duas versões do código, a IL do operador condicional parece mais curta que a instrução if-else, e ainda há uma dúvida do código da máquina finalmente gerado. A seguir, são apresentadas as instruções dos dois métodos, e a imagem anterior não é otimizada; a última é a otimizada:
Neste último, o bloco amarelo é o código executado somente se i<=0
, e o bloco azul é quando i>0
. Em qualquer versão das instruções, a instrução if-else é mais curta.
Observe que, para instruções diferentes, o [ CPI ] não é necessariamente o mesmo. Logicamente, para instruções idênticas, mais instruções custam um ciclo mais longo. Mas se o tempo de busca da instrução e o pipe / cache também foram levados em consideração, o tempo total real de execução depende do processador. O processador também pode prever as ramificações.
Os processadores modernos têm ainda mais núcleos; as coisas podem ser mais complexas com isso. Se você era um usuário de processador Intel, pode consultar o [ Manual de referência da otimização de arquiteturas Intel® 64 e IA-32 ].
Não sei se havia um CLR implementado por hardware, mas se sim, você provavelmente fica mais rápido com o operador condicional porque a IL é obviamente menor.
Nota: Todo o código da máquina é de x86.
DateTime
para medir o desempenho. UseStopwatch
. Em seguida, tempo um pouco mais longo - é um tempo muito curto para medir.