En C++, es el ?: operador más rápido que si()…else? ¿Hay diferencias entre ellos en el código compilado?

  • Difícil pregunta, ya que también dependerá de la configuración de optimización del compilador.
  • Que sin duda depende de lo que hagan en el interior de las ramas. El operador condicional permite que sólo las expresiones, mientras que if permite declaraciones.
  • relacionados: Para ternario o no ternario?
  • Un tipo al azar decidió editar mi perfectamente bien los tres años de edad pregunta, la reescritura de la pregunta, así que suena totalmente diferente a mí y la adición de algo totalmente innecesario código que hace que todo el problema inútil porque, gracias a la constante de plegado, tanto de las muestras de reducir a un simple «resultado = 5». Revertir.
  • Versión del ensamblado cmov vs jmp stackoverflow.com/questions/14131096/…
InformationsquelleAutor Xirdus | 2010-08-25

14 Comentarios

  1. 84

    Depende de su compilador, pero en cualquier compilador moderno en general no hay diferencia. Es algo que no debe preocuparse. Concentrarse en la mantenibilidad del código.

    • +1 Para muchas aplicaciones, el perf diferencia no vale la pena teniendo en cuenta que, incluso en una muy volcado compilador.
    • Con respecto a la mantenibilidad del código prefiero if…else. Al menos para mí es más fácil de leer.
    • Depende del contexto. El operador ternario es a menudo mejor cuando la inicialización de un objeto.
    • Por eso dije «Al menos para mí». Me refería a la legibilidad de código 🙂
    • Podría, por favor, pregunte, ¿CÓMO es un condicional menos fácilmente que un «si»? Si usted tiene dos igualdad de opciones, consistente en la elección de la más lenta es prematuro pessimization.
    • No estoy diciendo que un condicional es menos fácil de mantener que un si. Ambos son más claras en algunos, diferentes circunstancias, como se describe en las respuestas de la Para ternario o no ternario pregunta vinculado anteriormente.
    • Me llegó una cruz de un example en la que ternario selección impedía mover la construcción de ser usados, lo que resulta en copias adicionales en comparación con un if/else.
    • bastante antiguo post ya. Sin embargo, he leído esta respuesta y yo no entiendo por qué hay una diferencia entre el ternario y si-más cuando se trata de deducir el tipo de retorno (consulte la sección «Tipos de Retorno»). Yo quería hacer una pregunta sobre eso, pero luego me encontré con este y ahora estoy un poco insatisfecho con la respuesta 😉

  2. 93

    No es más rápido. Hay una diferencia cuando se puede inicializar una constante la variable dependiendo de algunos expresión:

    const int x = (a<b) ? b : a;

    Usted no puede hacer lo mismo con if-else.

    • Sí, con «if-else» primera inicialización con algún valor por defecto, a continuación, la asignación de un nuevo valor. Un par de más ciclos de procesador pasado.
    • Arte: Que no es posible con un const variable.
    • Usted podría crear un no-const variable, asigne en el if/else, a continuación, crear una nueva const variable y la construyen con el no-const. En lugar de despilfarro, pero lejos de ser imposible.
    • al final obtendrá una variable más en el mismo ámbito, que <strike>podría</strike>será confuso. Este no es el mismo.
    • Me dijo que era un desperdicio. Le has dado un ejemplo de una forma en la que es una basura. Pero es absolutamente imposible.
    • ¿Qué pasa cuando la inicialización de un miembro const?
    • Bueno que lambdas va a «resolver» esta para if/else 🙂 jaja
    • No puedes escribir una Integral de la Expresión de la Constante con if/else, pero usted puede con ?: . Esa es la diferencia real. Práctica: char foo[ a < b ? b : a ]; no puede escribirse con if/else; las declaraciones terminaría en el mal ámbitos.
    • Ni puede ser escrito con ?:, porque [a] debe ser no sólo const pero constexpr, que el resultado de ?: no, a menos que ambos a y b son constexprs, en cuyo caso ?: no compile para cualquier código de máquina. Edit: también se ubica, el argumento de que es en tiempo de ejecución.
    • ¿Qué acerca de good ol’ max? const int x = max(a,b); funciona bien.
    • ja! cuando he leído tu comentario pensé que el mando eai sugiriendo fue max ? const int x = max(a,b); y el pensamiento whoa! WTF es eso! luego leí de nuevo y noté el signo de interrogación no monoespaciado! dado el tema, creo que se justifica en el pensamiento ? fue parte del comando. 🙂
    • Usted puede utilizar const int x = [&] -> int { if (a < b) return b; else return a; }.

  3. 40

    He visto GCC gire el operador condicional en cmov (condicional mover) instrucciones, mientras gira if declaraciones en las ramas, lo que significaba en nuestro caso, el código fue más rápido cuando se utiliza el operador condicional. Pero eso fue hace un par de años, y lo más probable es hoy, y compilar el mismo código.

    No hay garantía de que va a compilar el mismo código. Si usted necesita el rendimiento de entonces, como siempre, medida. Y cuando se ha medido y se encontró que 1. su código es demasiado lento, y 2. es esta particular trozo de código que es el culpable, entonces, estudiar el código ensamblador generado por el compilador y comprobar por ti mismo lo que está sucediendo.

    No confían reglas de oro como «el compilador siempre va a generar código más eficiente si puedo usar el operador condicional».

    • +1. Cuando yo estaba en desarrollo para PS3 usando GCC, el uso de los condicionales en lugar de «si» fue útil para evitar las ramas.
    • Es específico para el lenguaje c? El estándar de c++ dice 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 al parecer evitar que el compilador genere una cmove instrucciones.
    • no, el C tiene la misma regla. Pero bajo el como-si la regla, el compilador es libre para engañar, siempre y cuando el resultado final es correcto. Así como hay no hay efectos secundarios, el compilador puede hacer esta optimización.
    • Cómo implementar si los demás con cmov? Un mov a el valor 1 + un cmov a valor 2 ?
    • NOTA : Este consejo es anticuado (cira 2010), que no puede reproducir este en gcc 4.4 o posterior.
  4. 15

    Son los mismos, sin embargo, el operador ternario puede ser utilizado en lugares donde es difícil usar un if/else:

    printf("Total: %d item%s", cnt, cnt != 1 ? "s" : "");

    Haciendo esa declaración con un if/else, generaría una muy diferente código compilado.


    Actualización después de 8 años…

    Realidad, creo que esto sería mejor:

    printf(cnt == 1 ? "Total: %d item" : "Total: %d items", cnt);

    (en realidad, estoy bastante seguro de que usted puede reemplazar el «%d» en la primera cadena con «uno»)

    • Ni siquiera necesita un operador ternario: printf("Total: %d item%s", cnt, "s" + (cnt==1));
    • pero que le da un doble nulo al final de la cadena, que puede ser un problema en otro situaciones de doble null significa algo (por ejemplo, en lpStrFilter miembro de la OPENFILENAME estructuras)
    • No. %s imprime hasta, pero no incluyendo el \0 de la cadena de origen.
    • ¿cómo funciona este printf("Total: %d item%s", cnt, "s" + (cnt==1)); trabajo?
    • es verdadero o falso, lo que convierte a 0 o 1. «s» es un puntero a un nul cadena terminada. La adición de uno salta de un personaje (s). Por lo que este se imprime «s» o «».
  5. 2

    Independientemente de que el código compilado, son semánticamente cosa diferente. <cond>?<true expr>:<false expr> es una expresión y if..else.. es una declaración.

    Aunque la sintaxis de la expresión condicional parece torpe, es una buena cosa. Usted está obligado a proporcionar un <false expr> y que las dos expresiones son comprueba el tipo de.

    El equivalente a if..else.. en la expresión basado en lenguajes funcionales como Lisp, Haskell es ? : en C++, en lugar de if..else.. declaración.

  6. 1

    Usted no está obligado a ponerlo todo en una sola línea:-

    x = y==1 ?
        2
        ://else
        3;

    Es mucho más clara que la de if/else, porque usted puede ver inmediatamente que ambas ramas conducir a x se le asignan.

    • También puede inicializar una constante
  7. 0

    Ahora yo no puedo ayudarte con eso, me pueden ayudar con una cuestión secundaria debajo de ella, no quiero usar? Si usted simplemente desea saber de la velocidad, simplemente ignorar mi comentario.

    Todo lo que puedo decir es que por favor ser muy inteligentes acerca de cuándo utilizar el ternario ? : operador. Puede ser una bendición como una maldición para mejorar la legibilidad.

    Pregúntese si usted encuentra que esto sea 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 para hacer que el código sea 100% falso. Pero ese pequeño truco me ayudó a analizar mi legibilidad del código. Es la legibilidad del operador que usted mira en este ejemplo, y no el contenido.

    Se VE limpio, pero también lo hace el promedio del asiento del inodoro y la perilla de la puerta

    En mi experiencia, que es limitado, he visto muy poco de la gente en realidad ser capaz de extradición de la información requiere de un operador ternario, evitar a menos que sea 100% seguro de que es mejor. Es un dolor de revisión cuando se molestaba, así que yo creo

    • primera línea probablemente debería leer int x = x == 1 ? 1 : 2 o posiblemente int x = (x == 1) ? 1 : 2
    • Mi punto era, simplemente, para mostrar el punto de vista del código, el cleanlyness de una línea es bonito, sí. Pero si quieres ver el estado de la ASIGNACION del contenido del código puede ser falso. Si desea detectar qué es lo que usted busca en el operador y el lugar solo. Veo la palabra SI y ( ) lo sé , ah , que es una condición. Veo A = B ? CONDICIÓN : CONDICIÓN hizo que immedeatly lugar que por sí mismo? La mayoría de la gente sé que el programa no se, tal vez es porque la mayoría de gente que conozco ese programa son novatos como yo. Estás en lo correcto de la ofc en los números de ser una tontería, ese es el punto.
    • Primera línea definitivamente necesidades de algunos de los paréntesis. Tal vez «int x = (y==1) ? 0 : 1;» o «int x = ((y==1) ? 0 : 1);»
    • Lo siento, pero no tengo ningún problema en ver la asignación. Si usted elige a complicarse demasiado el ejemplo para hacer su punto, ese es su problema. ¿Por qué no escribes x = x = 1; todas las partes y luego se quejan de que la tarea es demasiado complicado y debe evitarse.
  8. 0

    Yo esperaría que en la mayoría de los compiladores y las plataformas de destino, habrá casos en los que «si» es más rápido y los casos en que ?: es más rápido. También habrá casos donde una forma más o menos compacta que la de los otros. Que los casos a favor de una u otra forma va a variar entre los compiladores y las plataformas. Si usted está escribiendo cruciales para el rendimiento código incrustado micro, mira lo que el compilador genera en cada caso y ver cual es mejor. En una «corriente principal» de PC, debido a los problemas de cache, la única manera de ver lo que es mejor es comparar ambas formas en algo que se asemeja a la aplicación real.

  9. 0

    En C Un operador ternario » ? : «está disponible para la construcción de expresiones condicionales de la forma

    exp1 ? exp2:exp3

    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 puede ser escrito utilizando if..else la siguiente declaración de

                if (a>b)
                 x=a;
                 else
                 x=b;

    **Por lo tanto no hay ninguna diferencia entre estos dos. Esto para el programador facilidad para escribir, pero para el compilador de ambos son las mismas.*

  10. 0

    Durante revertir algunas código (el cual no recuerdo, hace unos años) me vi sola línea de diferencia entre el Código Máquina de 😕 y en el caso de los demás.
    Don't remember much but it is clear that implementation of both is different.

    Pero Te aconsejo que no elegir uno de ellos b’coz de su eficiencia, elegir de acuerdo a la legibilidad del código o su conveniencia.
    Feliz Codificación

    • La diferencia era que uno de ellos fue el uso de goto para la ramificación y el otro era el uso de saome nativo de la instrucción, no recuerdo cuál era el uso que..
  11. 0

    Operador ternario siempre devuelve un valor.
    Así, en la situación de que cuando quieres algo de valor de salida de resultado y sólo hay 2 condiciones siempre es mejor utilizar operador ternario.
    El uso de if-else si cualquiera de las condiciones mencionadas anteriormente no son verdad.

    • ¿Qué es exactamente esto? ¿Sabes de qué estás hablando?
  12. 0

    Creo que hay situaciones en las que la línea si puede producir «más rápido» de código debido a que el ámbito de aplicación es que funciona. Objeto de la creación y la destrucción puede ser costoso, así que considere la siguiente situación :

    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  

    Por alineaciones de la si, nos ahorramos un montón de operación necesarios para mantener a vivo en el mismo ámbito de aplicación que b. Aunque es muy probable que la evaluación de condición de velocidad es bastante iguales en ambos escenarios, el cambio de alcance obliga a tomar otros factores en cuenta que la línea si permite evitar.

    • ¿Y qué acerca de A a(true ? 5 : 10);
  13. -4

    No, que se convierten en exactamente el mismo código ejecutable.

    • -1: ¿Sobre qué versión de lo que el compilador, por lo que la plataforma, con lo que el código?
    • DeadMG: VB6 compilador, obviamente!

Dejar respuesta

Please enter your comment!
Please enter your name here