java performance boolean memory-footprint

Rendimiento de Java: true vs. Boolean.TRUE



performance memory-footprint (9)

¿Cuál es mejor en términos de rendimiento y uso eficiente de la memoria?

Boolean isItTrue(arg){ return Boolean.TRUE; } boolean isItTrue(arg){ return Boolean.TRUE } Boolean isItTrue(arg){ return true; } boolean isItTrue(arg){ return true; }

Debería ser más rápido y más fácil trabajar con tipos primitivos, pero por otro lado, cuando se usa referencia a un objeto estático, no se crea un nuevo valor. ¿O puede estar optimizado en el nivel del compilador y todo lo true y lo false son reemplazados por referencias a los objetos estáticos para ahorrar memoria?


El último

boolean isItTrue(arg){ return true; }

Utilizo Boolean solo si el método a veces necesita devolver null


En primer lugar, es muy probable que la ventaja de rendimiento de usar cualquiera sobre los demás sea demasiado pequeña para ser relevante. La simplicidad / legibilidad / mantenibilidad del código es mucho más importante ... en la gran mayoría de los casos.

Ninguno de los ejemplos implica crear una instancia Boolean . En teoría, es posible que 3 de los 4 desencadenen la inicialización de la clase Boolean ... y que su aplicación no hubiera hecho eso. En ese caso altamente improbable , toda la aplicación asignará 2 objetos que de otro modo no se habrían asignado.

Este será igual o más rápido que todos los demás porque simplemente implica establecer un registro en cero.

boolean isItTrue(arg){ return true; }

Tomado en forma aislada, esto tiene que cargar una referencia estática de la memoria, en lugar de poner a cero un registro. Sin embargo, el compilador JIT puede ser capaz de optimizar esto en algunas circunstancias.

Boolean isItTrue(arg){ return Boolean.TRUE; }

A primera vista, esto implica una llamada a Boolean.valueOf(true) para " Boolean.valueOf(true) " el true , pero el compilador JIT debería poder optimizarlo al mismo código que el anterior al incluir la llamada.

Boolean isItTrue(arg){ return true; }

A primera vista, esto implica una llamada a Boolean.booleanValue(Boolean.TRUE) para "desempaquetar" el Boolean . Esta llamada puede ser en línea. También es posible que el compilador JIT pueda evitar cargar la referencia al objeto Boolean y obtener su campo de valor.

boolean isItTrue(arg){ return Boolean.TRUE }

La conclusión es que el rendimiento relativo de las 4 alternativas depende de qué tan exitoso será el compilador JIT en la optimización. Eso dependerá del contexto, el específico del compilador JIT, la configuración de JVM, etc. En el mejor de los casos, el compilador JIT podría (al menos en teoría) producir el mismo código (óptimo) para todos ellos.


Favorecer la claridad para el mantenedor del código sobre dichas microoptimizaciones. La pregunta no debe ser "que es más pequeño / más rápido", primero que expresa lo que quieres decir.

Si el método devuelve un objeto booleano, quienquiera que lo reciba debe decidir si existe la posibilidad de que sea nulo, y si es nulo puede significar algo diferente de verdadero / falso, como "no sabemos".

Entonces, devuelva el tipo de booleano, si eso es lo que quiere decir, de lo contrario, si desea permitir Null, entonces booleano.

Si devuelve un booleano entonces

return true; // or false

debe ser mejor que confiar en el autoboxing, una vez más por claridad y rendimiento.

Si regresa booleano entonces

return Boolean.TRUE

debe ser bueno, simplemente evita crear basura adicional, por mucho que me oponga a la microoptimización, no veo ningún valor en ser voluntariamente ineficiente. Yo diría que también es más claro en el sentido de que usted está igualando visiblemente el tipo de retorno.


Mis reglas de oro son las siguientes:

  1. La opción predeterminada es el tipo primitivo ( boolean ).
  2. Si necesito nulabilidad o necesito almacenar los valores en un contenedor, uso la clase ( Boolean ).

Con esto en mente, mi elección por defecto sería:

boolean isItTrue(arg){ return true; }

En lo que respecta al rendimiento, lo único que parece seguro es que es difícil imaginar un escenario en el que el uso de Boolean sea más rápido que el de Boolean . Si sería más lento o lo mismo depende de muchas cosas y es imposible responder en general.

Si realmente te importa esto, ¡perfil el código donde importa!


Según esa lógica, la referencia al objeto estático en sí es tan costosa como el valor de verdad, si no más.

El uso de objetos puede ser algo más lento que los primitivos, pero no me preocuparía: la diferencia es irrelevante.


Serán mucho más rápidos. No creo que haya ninguna diferencia entre estos remolques.

Boolean isItTrue(arg){ return Boolean.TRUE; } boolean isItTrue(arg){ return true; }

Pero otras implementaciones serán más lentas porque el boxeo y el desempaquetado en el back-end llevarán algo de tiempo del procesador.

Editar

He recopilado algunos datos mediante la implementación de las 4 formas diferentes. Solo quiero compartirlo contigo, no lo hago si es la forma de escribir para hacer eso.

Boolean isItTrue(){ return Boolean.TRUE; } Free Memory before start --> 16030936 Time taken in Secs --> 7.844 Free Memory After Process --> 15940472 Memory Usage --> 90464

boolean isItTrue(){ return Boolean.TRUE; } Free Memory before start --> 16030936 Time taken in Secs --> 10.109 Free Memory After Process --> 15940472 Memory Usage --> 90464

Boolean isItTrue(){ return true; } Free Memory before start --> 16030936 Time taken in Secs --> 7.906 Free Memory After Process --> 15940472 Memory Usage --> 90464

boolean isItTrue(){ return true; } Free Memory before start --> 16030936 Time taken in Secs --> 7.828 Free Memory After Process --> 15940472 Memory Usage --> 90464

Clase principal

public static void main(String[] args){ NewClass n = new NewClass(); long sysTime = System.currentTimeMillis(); Runtime rt = Runtime.getRuntime(); long freeMem = rt.freeMemory(); System.out.println( "Free Memory before start --> " + freeMem ); for( int i = 0; i < Integer.MAX_VALUE; i++ ){ n.isItTrue(); } System.out.println( "Time taken in Secs --> " + (System.currentTimeMillis() - sysTime)/1000D); System.out.println( "Free Memory After Process --> " + rt.freeMemory() ); System.out.println( "Memory Usage --> " + ( freeMem - rt.freeMemory() ) ); }


Si hay algún aumento en el rendimiento, es tan minúsculo que es irrelevante. Boolean.TRUE y Boolean.FALSE no devuelven un nuevo objeto en ningún caso.


Usa el último (solo boolean ). Incluso si el compilador los optimiza a todos para la misma cosa, al menos estás haciendo el trabajo del compilador más fácil (¡no es un trabajo fácil, ya sabes!).

Además, hay menos pulsaciones de teclas (no es necesario presionar Mayús). Pero en realidad, la única razón por la que debería usar la clase contenedora es cuando necesita la capacidad de establecerla en null , y para usarla en estructuras de datos genéricos como LinkedList<E> .


java.lang.Boolean toma 16 bytes.

Este es el camino a seguir si solo está buscando problemas de rendimiento y tamaño de memoria:

boolean isItTrue(arg){ return true; }