Editar:
Se agregó un ejemplo que se puede hacer con la instrucción if-else pero no con el operador condicional.
Antes de la respuesta, eche un vistazo a [ ¿Cuál es más rápido? ] en el blog del Sr. Lippert. Y creo que la respuesta del Sr. Ersönmez es la más correcta aquí.
Estoy tratando de mencionar algo que debemos tener en cuenta con un lenguaje de programación de alto nivel.
En primer lugar, nunca escuché que el operador condicional se supone que sea más rápido o que tenga el mismo rendimiento con la instrucción if-else en C♯ .
La razón es simple: ¿qué pasa si no hay operación con la instrucción if-else?
if (i > 0)
{
value += 2;
}
else
{
}
El requisito del operador condicional es que debe haber un valor con cualquier lado, y en C♯ también requiere que ambos lados :
tengan el mismo tipo. Esto solo lo hace diferente de la declaración if-else. Por lo tanto, su pregunta se convierte en una pregunta que pregunta cómo se genera la instrucción del código de máquina para que la diferencia de rendimiento.
Con el operador condicional, semánticamente es:
Cualquiera que sea la expresión evaluada, hay un valor.
Pero con la declaración if-else:
Si la expresión se evalúa como verdadera, haga algo; si no, haz otra cosa.
Un valor no está necesariamente involucrado con la declaración if-else. Su suposición solo es posible con la optimización.
Otro ejemplo para demostrar la diferencia entre ellos sería el siguiente:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
if(i>0)
array1[1]=4;
else
array2[2]=4;
el código anterior compila, sin embargo, reemplace la instrucción if-else con el operador condicional simplemente no compilará:
var array1=new[] { 1, 2, 3 };
var array2=new[] { 5, 6, 7 };
(i>0?array1[1]:array2[2])=4; // incorrect usage
El operador condicional y las declaraciones if-else son conceptuales iguales cuando hace lo mismo, posiblemente incluso más rápido con el operador condicional en C , ya que C está más cerca del ensamblaje de la plataforma.
Para el código original que proporcionó, el operador condicional se usa en un bucle foreach, lo que desordenaría las cosas para ver la diferencia entre ellos. Entonces propongo el siguiente 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);
}
}
y las siguientes son dos versiones de la IL de optimizado y no. Como son largos, estoy usando una imagen para mostrar, el lado derecho es el optimizado:
(Haga clic para ver la imagen a tamaño completo).
En ambas versiones de código, la IL del operador condicional se ve más corta que la instrucción if-else, y todavía hay una duda sobre el código de máquina finalmente generado. Las siguientes son las instrucciones de ambos métodos, y la primera imagen no está optimizada, la segunda es la optimizada:
En este último, el bloque amarillo es el código que solo se ejecuta si i<=0
, y el bloque azul es cuando i>0
. En cualquier versión de instrucciones, la instrucción if-else es más corta.
Tenga en cuenta que, para diferentes instrucciones, el [ CPI ] no es necesariamente el mismo. Lógicamente, para la misma instrucción, más instrucciones cuestan un ciclo más largo. Pero si el tiempo de obtención de instrucciones y la canalización / caché también se tuvieron en cuenta, el tiempo total real de ejecución depende del procesador. El procesador también puede predecir las ramas.
Los procesadores modernos tienen incluso más núcleos, las cosas pueden ser más complejas con eso. Si usted fuera un usuario del procesador Intel, es posible que desee ver el [ Manual de referencia de optimización de arquitecturas Intel® 64 e IA-32 ].
No sé si hubo un CLR implementado en hardware, pero en caso afirmativo, es probable que sea más rápido con el operador condicional porque la IL es obviamente menor.
Nota: Todo el código de la máquina es de x86.
DateTime
para medir el rendimiento. UsoStopwatch
. Luego, el tiempo es bastante más largo: es un tiempo muy corto para medir.