Если узкое место достаточно большое, чтобы его можно было наблюдать с помощью профилировщика, используйте профилировщик.
Если вам нужна более высокая точность, лучшим способом измерения небольшого фрагмента кода является использование инфраструктуры микрообъектов Java, например OpenJDK's JMH или Google's Caliper. Я считаю, что они так же просты в использовании, как JUnit, и не только вы получите более точные результаты, но вы получите опыт сообщества, чтобы сделать все правильно.
Подписывается JMH microbenchmark для измерения времени выполнения Math.log()
:
private double x = Math.PI;
@Benchmark
public void myBenchmark() {
return Math.log(x)
}
Использование currentMillis()
и nanoTime()
для измерения имеет много ограничений:
- Они имеют задержку (они также требуют времени, чтобы выполнить), которые смещают ваши измерения.
- Они ОЧЕНЬ ограниченной точности, это означает, что вы можете MESURE вещей от 26ns к 26ns в Linux и 300 или так в Windows, описало here
- фазы прогрева не принимаются во внимание, что делает ваши измерения колеблются МНОГО.
В currentMillis()
и nanoTime()
методе в Java может быть полезна, но должна быть использована с EXTREME ВНИМАНИЯ или вы можете получить Неправильные ошибки измерений like this где порядок измеряемых фрагментов влияют на измерения или like this где автор ошибочно заключить что несколько миллионов операций, выполняемых менее чем за миллисекунду, когда на самом деле JMV не реализовал никаких операций, в которых был сделан и поднял код, вообще не выполняя никакого кода.
Вот замечательные видео, объясняющие, как microbenchmark правильного пути: https://shipilev.net/#benchmarking
Вы должны использовать 'System.nanoTime()' для измерения * истекшее время * (см http://stackoverflow.com/questions/238920/quick-question-java-system-clock/ 239661 # 239661), а не 'System.currentTimeMillis()'. Другие пункты (разминка, JIT), упомянутые @Stephen в комментарии, остаются в силе. –
Используйте класс секундомера для этой задачи –