Статический блок против статического метода - инициализация статических полей - PullRequest
8 голосов
/ 19 ноября 2011

Из любопытства я измерил производительность между статическим блоком и инициализатором статического метода.Во-первых, я реализовал вышеупомянутые методы в двух отдельных классах Java, например:

Первый:

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);    
    }
}

Второй:

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);    
    }
}

Затем я выполнил этот маленький пакетный скрипт, чтобы измерить его 100 раз и поместить значения в файл.batchFile.bat First Second dum.res.txt

После этого я написал этот фрагмент кода для вычисления среднего значения и стандартного отклонения измеренных значений Dummy и Muddy.

Вот результат, который я получил:

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

И он похож на другие мои машины ... каждый раз, когда я проверяю его.

Теперь ямне интересно, почему это так?Я проверил байт-код, и Second.class имеет еще одну инструкцию (вызов static initList ()) между вызовами System.currentTimeMillis ().Они оба делают одно и то же, но почему Первый медленнее?Я не могу понять это, просто посмотрев на байт-код, так как я впервые коснулся javap ;Я еще не понимаю байт-код.

Ответы [ 2 ]

2 голосов
/ 19 ноября 2011

Вот мое предположение относительно причины этого:

При инициализации вы создаете достаточно объектов, которые вызывают одну или несколько сборок мусора.

Когда инициализация вызывается из статического блока, она выполняется во время инициализации класса, а не во время выполнения простого метода. Во время инициализации класса у детектора мусора может быть немного больше работы (например, потому что стек выполнения длиннее), чем во время простого выполнения метода, даже если содержимое кучи почти одинаково.

Чтобы проверить это, вы можете попробовать добавить -Xms200m или что-то в ваши команды java; это должно устранить необходимость сбора мусора во время инициализации, которую вы делаете.

2 голосов
/ 19 ноября 2011

Я думаю, что причина, по которой версия статического блока медленнее, чем версия статического метода, может быть связана с другой оптимизацией JIT, которую они получают ...

См. Эту интересную статью для получения дополнительной интересной информации: Секрет Java: интерпретируются ли статические блоки?

...