2011-11-18 15 views
8

Por curiosidad, medí el rendimiento entre el bloque estático y el inicializador de método estático. En primer lugar, he implementado los métodos mencionados anteriormente en dos clases de Java independientes, así:Bloque estático vs método estático - inicialización de campos estáticos

primera:

class Dummy { 
    static java.util.List<Integer> lista = new java.util.ArrayList<Integer>(); 
    static { 
     for(int i=0; i < 1000000; ++i) { 
      lista.add(new Integer(i)); 
     } 
    } 
} 

public class First { 
    public static void main(String[] args) { 
     long st = System.currentTimeMillis(); 
      Dummy d = new Dummy(); 
     long end = System.currentTimeMillis() - st; 
     System.out.println(end);  
    } 
} 

Segundo:

class Muddy { 
    static java.util.List<Integer> lista = new java.util.ArrayList<Integer>(); 
    public static void initList() { 
     for(int i=0; i < 1000000; ++i) { 
      lista.add(new Integer(i)); 
     } 
    } 
} 

public class Second { 
    public static void main(String[] args) { 
     long st = System.currentTimeMillis(); 
      Muddy.initList(); 
      Muddy m = new Muddy(); 
     long end = System.currentTimeMillis() - st; 
     System.out.println(end);  
    } 
} 

Entonces ejecutados this pequeño script por lotes para medirlo 100 veces y poner los valores en un archivo. batchFile.bat First Second dum.res.txt

Después de eso, escribí this pieza de código para calcular el valor medio y la desviación estándar de los valores medidos de Dummy y Muddy.

Este es el resultado de que tengo:

First size: 100 Second size: 100 
First  Sum: 132 Std. deviation: 13 
Second  Sum: 112 Std. deviation: 9 

y es similar en mis otras máquinas ... cada vez que lo prueba.

Ahora me pregunto, ¿por qué es así? Comprobé el bytecode y Second.class tiene una instrucción más (llamar a staticListList()) entre llamadas a System.currentTimeMillis(). Ambos hacen lo mismo, pero ¿por qué es el primero más lento? Realmente no puedo razonar con solo mirar el bytecode, ya que esta era la primera vez que toco javap; Todavía no entiendo bytecode.

+0

Intente invertir primero y segundo en su llamada a la secuencia de comandos por lotes y vea cuáles son los resultados :) – antlersoft

+0

El número de instrucciones no tiene nada que ver con cuánto tiempo tardan esas instrucciones (pidiéndole que conduzca por la ciudad o en todo el país - bueno, a menos que vivas en Lichenstein o algo así). ¿Son exactamente las mismas instrucciones? Yo más bien lo dudo. En una nota lateral, dudaría en usar tu segunda versión, incluso si es más rápida, depende de hacer esa llamada 'initList()', algo con lo que nunca contaría. –

+0

@antlersoft Devuelve los mismos resultados. Ya lo probé. – Mechkov

Respuesta

2

creo que la razón por la versión de bloque estático es más lento que la versión método estático podría ser debido a la diferente optimización JIT que consiguen ...

Ver este interesante artículo para obtener información más interesante: Java Secret: Are static blocks interpreted?

2

Aquí es mi conjetura en cuanto a la razón de esto:

la inicialización que está haciendo es crear suficientes objetos que está causando una o más colecciones de basura.

Cuando se llama a la inicialización desde el bloque estático, se realiza durante la inicialización de la clase en lugar de durante la ejecución del método simple. Durante la inicialización de la clase, el detector de basura puede tener un poco más de trabajo por hacer (porque la pila de ejecución es más larga, por ejemplo) que durante la ejecución de un método simple, aunque el contenido del montón sea casi el mismo.

Para probar esto, puede intentar agregar -Xms200m o algo similar a sus comandos java; esto debería eliminar la necesidad de recolectar basura durante la inicialización que estás haciendo.

Cuestiones relacionadas