¿Hay alguna diferencia de rendimiento entre usar int a = a + 1 y a ++ en java? Si es así, ¿cuál es mejor y por qué?

¿Podrías explicarme brevemente para entender esto?

Mirando el bytecode generado:

public static void main(String[] args) { int x = 1; int y = 1; int z = 1; int a = 1; int b = 1; x = x + 1; y++; ++z; a += 1; b += 2; } 

genera (use javap -c classname )

 0: iconst_1 1: istore_1 2: iconst_1 3: istore_2 4: iconst_1 5: istore_3 6: iconst_1 7: istore 4 9: iconst_1 10: istore 5 12: iload_1 13: iconst_1 14: iadd 15: istore_1 16: iinc 2, 1 19: iinc 3, 1 22: iinc 4, 1 25: iinc 5, 2 28: return 

Entonces usando (jdk1.6.0_18):

 x = x + 1 

crea

 12: iload_1 13: iconst_1 14: iadd 15: istore_1 

mientras

 y++; ++z; a += 1; 

todo resulta en

 iinc 

Sin embargo, hacer una prueba de rendimiento aproximada en mi computadora portátil resultó en casi ninguna diferencia en el tiempo de ejecución entre las dos (a veces ++ x fue más rápido, a veces x = x + 1 fue más rápido), así que no me preocuparía por las implicaciones de rendimiento .

En primer lugar, la especificación del lenguaje Java no dice nada sobre el tiempo. Pero suponiendo que estemos usando un comstackdor típico como Suns javac, veremos que todos los ejemplos anteriores ( a++ , ++a , a += 1 , a = a + 1 ) podrían comstackrse en algo como:

  • Instrucción iinc , trabajando en variables:

     iload_ iinc , 1 istore_ 
  • iadd instuction, usando la stack (aquí usando la variable 1 como almacenamiento):

     iload_1 iconst_1 iadd istore_1 

Depende del comstackdor elegir la mejor manera posible de comstackrlos. Por ejemplo, no hay diferencia entre ellos. Y no debería haber ninguna diferencia entre las afirmaciones, todas expresan lo mismo: agregar una a un número.

Dicho esto, tanto la iinc como la versión iadd se pueden comstackr usando el JIT para algo rápido y dependiente de la plataforma, y ​​al final supondría que un tiempo de ejecución normal comstack ambas versiones en el mismo código de ensamblador.


Con mi comstackdor, * jdk1.6.0_20 * los métodos de “incremento” incluso usan la misma instrucción.

 public class Test { public static void main(String[] args) { int a = 0; a = a + 1; a += 1; a++; ++a; } } 

Este es el desassembly:

 Compiled from "Test.java" public class Test extends java.lang.Object{ public Test(); Code: 0: aload_0 1: invokespecial #8; //Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]); Code: 0: iconst_0 1: istore_1 2: iinc 1, 1 // a = a + 1; 5: iinc 1, 1 // a += 1; 8: iinc 1, 1 // a++; 11: iinc 1, 1 // ++a; 14: return } 

No, no habrá ninguna diferencia notable. Use lo que encuentre más legible (que es a++ , normalmente).

Primera regla de optimización de código: no.

El comstackdor debería optimizar y no debería haber diferencia alguna. Pero tenga en cuenta que el operador de incremento de prefijo puede ser (depende del comstackdor) más rápido que el equivalente de postfix (también en C ++ y C #):

++a más rápido que a++ porque el operador de postfix debe crear una variable temporal … piense en su implementación:

prefijo:

 a = a + 1; return a; 

sufijo:

 int tmp = a; a = a + 1; return tmp; 

a ++ es mucho más rápido. Se convierte al comando INC de assembler. Pero creo que JVM optimizará a = a + 1 para que no tenga que preocuparse por eso.

Es lo mismo, y hoy en día, con la optimización del comstackdor, no debería estar al tanto de eso, para boost su rendimiento, verifique otros problemas más importantes como la asignación 🙂