Java System.nanoTime истекшее среднее время продолжает уменьшаться - PullRequest
0 голосов
/ 15 марта 2012

Это не первый раз, когда у меня возникают проблемы с часами на языке программирования.По сути, я измеряю скорость выполнения функции, вызывая ее в цикле while.Проблема в том, что по какой-то причине прошедшее время становится короче, чем дольше работает цикл while.Кто-нибудь может объяснить?Код ниже.

DescriptiveStatistics stats = new DescriptiveStatistics();
while(true) {
    long startTime = System.nanoTime();
    executeSaxonXsltTransformation();
    long stopTime = System.nanoTime();
    long elapsedTime = stopTime-startTime;
    stats.addValue((double)elapsedTime);
    System.out.println(stats.getN()+" - "+elapsedTime+ " - "+stats.getMean());
}

Таким образом, после примерно 1000 запусков прошедшее время составляет от 750 до 850 КБ.Но после примерно 100 000 запусков истекшее время падает с 580 до 750 тысяч.Непрерывное снижение лучше всего наблюдать по среднему значению (stats.getMeans ()), которое после циклов 108k имеет в среднем ~ 632k по сравнению с циклами 3k со средним значением ~ 1 миллион.Переключение на currentTimeMillis вместо nanoTime ничего не меняет.

Ответы [ 2 ]

7 голосов
/ 15 марта 2012

Проблема в том, что по какой-то причине истекшее время становится короче, чем дольше работает цикл while. Кто-нибудь может объяснить?

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

4 голосов
/ 15 марта 2012

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

Если вы пытаетесь провести эталонный тест, вы должны «прогреть» эталонный тест, запустив метод в течение нескольких секунд без учета времени, и только после этого приступить к определению времени. В качестве альтернативы, вы можете использовать библиотеку, которая знает, как проводить последовательный бенчмаркинг в Java - прогревать JIT, получать точные измерения, если ваш метод занимает наносекунды или секунды - как Caliper .

...