Páginas

viernes, 25 de mayo de 2012

Boolean.TRUE versus true

El otro día comentábamos en el trabajo si era mejor, en cuanto a rendimiento, que en un método booleano se devolviese true o se devolviese Boolean.TRUE. Como en estas cuestiones mas vale una prueba que 2 horas de elucubraciones, tiramos el siguiente código:

public class AppTest {

    private static final int NUM_VUELTAS = 1000000000;

    public static void main(String[] args) throws Exception {
      
        long inic = System.currentTimeMillis();
        for (int x=0;x<NUM_VUELTAS;x++){
            for (int y=0;y<NUM_VUELTAS;y++){
                returnTrue1();
            }
        }
        System.out.println("return (boolean)true:"+(System.currentTimeMillis()-inic)+"ms");
      
        inic = System.currentTimeMillis();
        for (int x=0;x<NUM_VUELTAS;x++){
            for (int y=0;y<NUM_VUELTAS;y++){
                returnTrue2();
            }
        }
        System.out.println("return (boolean)true:"+(System.currentTimeMillis()-inic)+"ms");
      
        inic = System.currentTimeMillis();
        for (int x=0;x<NUM_VUELTAS;x++){
            for (int y=0;y<NUM_VUELTAS;y++){
                returnTrue3();
            }
        }
        System.out.println("return (boolean)true:"+(System.currentTimeMillis()-inic)+"ms");
      
        inic = System.currentTimeMillis();
        for (int x=0;x<NUM_VUELTAS;x++){
            for (int y=0;y<NUM_VUELTAS;y++){
                returnTrue4();
            }
        }
        System.out.println("return (boolean)true:"+(System.currentTimeMillis()-inic)+"ms");
    }
 
    private static boolean returnTrue1(){
        return true;
    }
 
    private static boolean returnTrue2(){
        return Boolean.TRUE;
    }
 
    private static Boolean returnTrue3(){
        return true;
    }
 
    private static Boolean returnTrue4(){
        return Boolean.TRUE;
    }
}
Los resultados, tras la primera ejecución los resultados parecían confusos:

return (boolean)true:6ms
return (boolean)Boolean.TRUE:4ms
return (Boolean)true:5ms
return (Boolean)Boolean.TRUE:4ms
Pero alterando el orden de las llamadas la confusión se disipó:

return (boolean)Boolean.TRUE:7ms
return (Boolean)true:5ms
return (Boolean)Boolean.TRUE:4ms
return (boolean)true:4ms
return (Boolean)true:7ms
return (Boolean)Boolean.TRUE:4ms
return (boolean)true:4ms
return (boolean)Boolean.TRUE:4ms




return (Boolean)Boolean.TRUE:7ms
return (boolean)true:4ms
return (boolean)Boolean.TRUE:4ms
return (Boolean)true:5ms

Resumiendo los tiempos:

  • returnTrue1: 6+4+4+4 --> 18 
  • returnTrue2: 4+7+4+4 --> 19 
  • returnTrue3: 5+5+7+5 --> 22 
  • returnTrue4: 4+4+7+7 --> 22

Analizando qué hace cada método:
  • returnTrue1. Devuelve un true. 
  • returnTrue2. Lee a una dirección de memoria y devuelve un "autounboxing" de su contenido. 
  • returnTrue3. Hace un "autoboxing" sobre un true. 
  • returnTrue4. Devuelve una dirección  de memoria.
A mi entender, los resultados de más rápido a más lento deberían haber sido:
  • returnTrue1 y returnTrue4. Igual de rápidas. 
  • returnTrue3.
  • returnTrue2.
Conclusión. Discutir sobre qué es más óptimo en este tema es perder el tiempo, dado que parece depender en gran medida de las optimizaciones internas del compilador. Es mas interesante elegir la opción que de mas claridad al código. 

Nota. Sobre autoboxing y autounboxing.

autounboxing. Es la transformación de objeto a tipo básico, por dentro se realiza una llamada a Boolean.booleanValue(Boolean.TRUE):

   boolean boolVar = Boolean.TRUE;

autoboxing. Es la otra transformación de tipo básico a objeto, por dentro se realiza una llamada a Boolean.valueOf(true):

   Boolean boolVar = true;

No hay comentarios:

Publicar un comentario