2011-09-19 22 views
10

En x = x + 1, ¿se evalúa x dos veces? Si es así, ¿significa eso en x += 1, x solo se evalúa una vez? ¿Cómo se evalúan las dos expresiones en términos del código intermedio del compilador?¿Es x + = 1 más eficiente que x = x + 1?

Por ejemplo, podría significar x++: tomar la ubicación de x, cargar el contenido del x en un registro, e incrementar el valor de x en la memoria.

También he leído que x += 1 es útil cuando x no es una variable simple, sino una expresión que involucra una matriz. ¿Alguna idea de por qué este es el caso?

+11

Esto suena como una gran cantidad de suposiciones infundadas, en particular el título. No veo una razón por la que uno deba ser más eficiente que el otro y estoy razonablemente seguro de que no es el caso en la mayoría de los compiladores de C. –

+3

Un compilador que vale la pena el dinero que pagó compilará ambas expresiones en el mismo código de objeto. Si le preocupa el rendimiento: ** mida **, mida código diferente, diferentes indicadores de compilación, diferentes usos de recursos, diferentes cosas. – pmg

+4

¿Sabes que x + = 1 es más eficiente que x = x + 1? ¿Has mirado el código objeto generado? – Joe

Respuesta

12

En la mayoría de los compiladores de estos serían idénticos

+1

¿qué pasa con los compiladores anteriores? que no se optimizan tanto como los más nuevos ... ¿Por qué se evalúan de forma diferente? – user7

+1

Si el compilador es ineficiente, puede ignorar el hecho de que x se refiere dos veces y cargarlo y luego realizar la operación de incremento en el valor cargado. – Ofir

+0

y ¿qué pasa con el comentario sobre las matrices? – user7

3

Así que ya hay algunas preguntas que cubren lo que está pidiendo aquí:

x=x+1 vs. x +=1

Incrementing: x++ vs x += 1

Which is faster? ++, += or x + 1?

El El resultado final es que en la mayoría de los casos pero no todos idiomas el compilador los hará idénticos de todos modos, por lo que no hay diferencia en cuanto a la eficacia. Las preguntas anteriores entran en un poco de detalle sobre el tema.

0

Con gcc, puede obtener el código de ensamblador con gcc -S foo.c. Lo intenté con x += 1 y x = x + 1 y fue lo mismo.

7

¿Por qué es x + = 1 más eficiente que x = x + 1?

No lo es.

¿Por qué x ++ es más eficiente que x + = 1?

No lo es.


La razón para preferir a x += 1x = x+1 se produce cuando x se sustituye con un identificador mucho más tiempo, o tal vez un campo de una clase o estructura. En esa situación, la versión x += 1 es más legible y, lo que es más importante, evita los inconvenientes de repetirse.

0

Debido a que toma 4 caracteres para escribir en lugar de 5.

Ésta es la única manera en la que x+=1 es "más eficiente" que x=x+1. Sin embargo, el operador += tiene algunas otras ventajas, como el hecho de que (x)+=1 funciona en macros donde x es una expresión que puede tener efectos secundarios que desea evitar evaluar más de una vez ...

11

Sólo para dar un "mundo real" ejemplo, considere este programa:

int main() 
{ 
    int i = 0; 
    i += 1; 
    i++; 
    i = i + 1; 
    return 0; 
} 

Compilarlo con GCC, en Darwin 11 con las siguientes banderas:

  • -S parada en ensamblador
  • -m32 a la plataforma de 32 bits, sólo para simplificar las cosas un poco

Generará el siguiente programa, a excepción de los comentarios y líneas en blanco que agregué. Eche un vistazo especialmente en los comentarios.

 .section  __TEXT,__text,regular,pure_instructions 
     .globl _main 
     .align 4, 0x90 
_main: 
     pushl %ebp    # cdecl function stuff 
     movl %esp, %ebp  # 
     subl $12, %esp   # get room for variables  
     movl $0, -12(%ebp)  # i = 0; 

     ; i += 1 
     movl -12(%ebp), %eax # load i in register a 
     addl $1, %eax   # add 1 to register a 
     movl %eax, -12(%ebp) # store it back in memory 

     ; i++ 
     movl -12(%ebp), %eax # 
     addl $1, %eax   # just the same 
     movl %eax, -12(%ebp) # 

     ; i = i + 1 
     movl -12(%ebp), %eax # 
     addl $1, %eax   # just the same 
     movl %eax, -12(%ebp) # 

     movl $0, -8(%ebp) 
     movl -8(%ebp), %eax 
     movl %eax, -4(%ebp) 
     movl -4(%ebp), %eax 
     addl $12, %esp 
     popl %ebp 
     ret 

.subsections_via_symbols 
+0

No sé por qué esto no está marcado como la respuesta, ya que proporciona una prueba y no solo una opinión. – nhouser9

+0

Esto debe marcarse como la respuesta. ¿También encontramos alguna diferencia en otros compiladores o sigue el mismo patrón? – SanVed

+1

@SanVed Gracias. Difícil de decir, teniendo en cuenta la cantidad de compiladores. Pero cualquier compilador con un desarrollo decente probablemente contenga esta "inteligencia". Los compiladores no son solo traductores directos de alto a bajo nivel, hay toda una ciencia involucrada y ejemplos como este se encuentran entre los elementos más básicos y primeros de esta ciencia. Entonces cualquier compilador moderno y principal debería incluirlo. – sidyll

Cuestiones relacionadas