En C ++, ¿el operador?: Es más rápido que las declaraciones if () ... else? ¿Existen diferencias entre ellos en el código compilado?
c++
performance
conditional-operator
Xirdus
fuente
fuente
if
permite declaraciones.Respuestas:
Depende de su compilador, pero en cualquier compilador moderno generalmente no hay diferencia. Es algo de lo que no debes preocuparte. Concéntrese en la mantenibilidad de su código.
fuente
No es mas rapido. Hay una diferencia cuando puede inicializar una variable constante dependiendo de alguna expresión:
const int x = (a<b) ? b : a;
No puedes hacer lo mismo con
if-else
.fuente
const
variable.max
?const int x = max(a,b);
funciona bien.max ? const int x = max(a,b);
y pensé: ¡Que demonios es eso! luego lo leí de nuevo y noté que el signo de interrogación no era monoespacio. dado el tema, creo que estaba justificado pensar en el? era parte del comando! :)const int x = [&] -> int { if (a < b) return b; else return a; }
.He visto a GCC convertir el operador condicional en
cmov
instrucciones (movimiento condicional), mientras convierte lasif
declaraciones en ramas, lo que significa que en nuestro caso, el código era más rápido cuando se usaba el operador condicional. Pero eso fue hace un par de años, y lo más probable es que hoy, ambos se compilen con el mismo código.No hay garantía de que se compilen con el mismo código. Si necesita el rendimiento, como siempre, mida . Y cuando haya medido y averiguado que 1. su código es demasiado lento, y 2. es este fragmento particular de código el culpable, estudie el código ensamblador generado por el compilador y compruebe usted mismo lo que está sucediendo.
No confíe en reglas de oro como "el compilador siempre generará un código más eficiente si uso el operador condicional".
fuente
Only one of the second and third expressions is evaluated. Every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second or third expression.
que aparentemente evita que el compilador generecmove
instrucciones.Son iguales, sin embargo, el operador ternario se puede usar en lugares donde es difícil usar un if / else:
printf("Total: %d item%s", cnt, cnt != 1 ? "s" : "");
Hacer esa declaración con un if / else, generaría un código compilado muy diferente.
Actualización después de 8 años ...
De hecho, creo que esto sería mejor:
printf(cnt == 1 ? "Total: %d item" : "Total: %d items", cnt);
(de hecho, estoy bastante seguro de que puede reemplazar "% d" en la primera cadena con "uno")
fuente
printf("Total: %d item%s", cnt, "s" + (cnt==1));
lpStrFilter
miembro de las estructuras OPENFILENAME )%s
imprime hasta, pero sin incluir el\0
de la cadena de origen.printf("Total: %d item%s", cnt, "s" + (cnt==1));
?(cnt==1)
es verdadero o falso, que se convierte en 0 o 1. "s" es un puntero a una cadena terminada en nulo. Agregar uno omite un carácter (los). Así que imprime "s" o "".Solo para ser un poco zurdo ...
asignará valor a y si x no es 0 (falso).
fuente
Independientemente del código compilado, son algo semánticamente diferente.
<cond>?<true expr>:<false expr>
es una expresión yif..else..
es una declaración.Aunque la sintaxis de la expresión condicional parece incómoda, es algo bueno. Está obligado a proporcionar un
<false expr>
y se verifica el tipo de las dos expresiones.El equivalente a
if..else..
en lenguaje funcional basado en expresiones como Lisp, Haskell está? :
en C ++, en lugar deif..else..
declaración.fuente
No está obligado a ponerlo todo en una sola línea: -
x = y==1 ? 2 :// else 3;
Es mucho más claro que if / else porque puede ver inmediatamente que ambas ramas conducen a la asignación de x.
fuente
Esperaría que en la mayoría de los compiladores y plataformas de destino, haya casos en los que "si" sea más rápido y casos en los que?: Sea más rápido. También habrá casos en los que una forma sea más o menos compacta que la otra. Los casos que favorezcan una forma u otra variarán entre compiladores y plataformas. Si está escribiendo código de rendimiento crítico en un micro integrado, mire lo que genera el compilador en cada caso y vea cuál es mejor. En una PC "convencional", debido a problemas de almacenamiento en caché, la única forma de ver cuál es mejor es comparar ambas formas en algo parecido a la aplicación real.
fuente
En CA, el operador ternario "?:" Está disponible para construir expresiones condicionales de la forma
donde exp1, exp2 y exp3 son expresiones
por ejemplo
a=20; b=25; x=(a>b)?a:b; in the above example x value will be assigned to b;
Esto se puede escribir usando la declaración if..else de la siguiente manera
if (a>b) x=a; else x=b;
** Por tanto, no hay diferencia entre estos dos. Esto para que el programador lo escriba fácilmente, pero para el compilador ambos son iguales. *
fuente
Durante la reversión de algún código (que no recuerdo, hace unos años) vi una diferencia de una sola línea entre el código de máquina de:? y si-si no.
Don't remember much but it is clear that implementation of both is different.
Pero te aconsejo que no elijas uno de ellos por su eficacia, elige según la legibilidad del código o tu conveniencia. Codificación feliz
fuente
Ternary Operator siempre devuelve un valor. Entonces, en una situación en la que desea algún valor de salida del resultado y solo hay 2 condiciones, siempre es mejor usar el operador ternario. Utilice if-else si alguna de las condiciones mencionadas anteriormente no es cierta.
fuente
Creo que hay situaciones en las que el if en línea puede producir un código "más rápido" debido al alcance en el que trabaja. La creación y destrucción de objetos puede ser costosa, así que considere el siguiente escenario:
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; }
Con este código, la salida será:
Default ctor Overloaded ctor = operator destroyed destroyed Next test Overloaded ctor destroyed
Entonces, al insertar el if, ahorramos un montón de operaciones necesarias para mantener
a
vivo en el mismo alcance queb
. Si bien es muy probable que la velocidad de evaluación de la condición sea bastante igual en ambos escenarios, cambiar el alcance lo obliga a tener en cuenta otros factores que el en línea le permite evitar.fuente
A a(true ? 5 : 10);
Ahora no puedo ayudarte con eso, es posible que pueda ayudarte con una pregunta secundaria debajo, ¿quiero usarlo? Si solo desea conocer la velocidad, simplemente ignore mi comentario.
Todo lo que puedo decir es que sea muy inteligente sobre cuándo usar el ternario. : operador. Puede ser una bendición tanto como una maldición para la legibilidad.
Pregúntese si le resulta más fácil de leer antes de usarlo
int x = x == 1 ? x = 1 : x = 1; if (x == 1) { x = 1 } else { x = 2 } if (x == 1) x = 1 else x = 1
Sí. Parece estúpido hacer que el código sea 100% falso. Pero ese pequeño truco me ayudó a analizar la legibilidad del código. Es la legibilidad del operador que observa en esta muestra, y no el contenido.
Parece limpio, pero también lo hace el asiento de inodoro y el pomo de la puerta promedio.
En mi experiencia, que es limitada, he visto a muy poca gente que realmente pueda extraditar rápidamente la información requerida de un operador ternario, evítelo a menos que esté 100% seguro de que es mejor. Es un dolor arreglarlo cuando también tiene micrófonos, creo
fuente
int x = x == 1 ? 1 : 2
o posiblementeint x = (x == 1) ? 1 : 2
x = x = 1;
todas partes y luego se queja de que la tarea es demasiado complicada y debe evitarse?No, se convierten exactamente en el mismo código ejecutable.
fuente