Зачастую требуется узнать, сколько времени выполняется тот или иной код. Иногда требуется замерить время выполнения метода или какой-то задачи. В данной статье мы расскажем вам принципы замера времени в Java и покажем лучшие практики для конкретных задач.
Замер времени с помощью currentTimeMills()
Это довольно простой способ измерить время. Метод System.currentTimeMillis() вернёт вам текущее время в миллисекундах. Его потребуется вызвать до выполнения нужной задачи и после, а затем вычислить разницу. В итоге мы узнаем время выполнения в миллисекундах:
long start = System.currentTimeMillis(); // выполнение какой-то логики Thread.sleep(1000); long finish = System.currentTimeMillis(); long elapsed = finish - start; System.out.println("Прошло времени, мс: " + elapsed);
При работе с данным методом следует учитывать его специфику: System.currentTimeMillis() показывает текущее время, основываясь на системных часах и может выдавать некорректный результат.
Замер времени с помощью nanoTime()
Ещё один метод для получения текущего времени это System.nanoTime(). Как следует из названия, этот метод возвращает время с точностью до нансекунд. Также работа этого метода не зависит от системных часов.
Он используется аналогично:
long start = System.nanoTime(); // выполнение какой-то логики Thread.sleep(1000); long finish = System.nanoTime(); long elapsed = finish - start; System.out.println("Прошло времени, нс: " + elapsed);
Для получения значения в миллисекундах результат можно разделить на 1000:
System.out.println("Прошло времени, мс: " + elapsed / 1000000);
Важно: Хотя метод nanoTime() может возвращать время в наносекундах, он не гарантирует, что значения между его вызовами будут обновляться с точностью до наносекунд.
Но всё же это более приемлемый вариант, чем System.currentTimeMillis().
Замер времени с помощью Instant и Duration
В Java 8 добавили новый java.time API. В частности, ля измерения времени подойдут два новых класса – Instant и Duration. Оба эти класса иммутабельны.
Instant обозначает момент времени с начала эпохи Unix (1970-01-01T00:00:00Z). Для создания момента мы используем метод Instant.now(). После того, как мы создали два момент, вычислим разницу в миллисекундах:
Instant start = Instant.now(); // выполнение какой-то логики Thread.sleep(1000); Instant finish = Instant.now(); long elapsed = Duration.between(start, finish).toMillis(); System.out.println("Прошло времени, мс: " + elapsed);
Рекомендуется использовать именно этот подход в Java 8 и выше.
Замер времени выполнения с помощью StopWatch
StopWatch – это класс из библиотеки Apache Commons Lang. Он работает как секундомер. Для его использования сначала требуется подключить библиотеку к проекту:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.9</version> </dependency>
Теперь создадим экземпляр StopWatch. Затем начнём отсчёт с помощью метода start() и окончим отсчёт с помощью метода stop():
public static void stopWatch() throws InterruptedException { StopWatch stopWatch = new StopWatch(); stopWatch.start(); // выполнение какой-то логики Thread.sleep(1000); stopWatch.stop(); System.out.println("Прошло времени, мс: " + stopWatch.getTime()); }
StopWatch удобно использовать тогда, когда в проекте уже подключена данная библиотека.
Исходный код
package ru.javalessons.time; import org.apache.commons.lang3.time.StopWatch; import java.time.Duration; import java.time.Instant; public class MeasureElapsedTime { public static void main(String[] args) throws InterruptedException { currentTimeMillis(); nanoTime(); instant(); stopWatch(); } public static void currentTimeMillis() throws InterruptedException { long start = System.currentTimeMillis(); // выполнение какой-то логики Thread.sleep(1000); long finish = System.currentTimeMillis(); long elapsed = finish - start; System.out.println("Прошло времени, мс: " + elapsed); } public static void nanoTime() throws InterruptedException { long start = System.nanoTime(); // выполнение какой-то логики Thread.sleep(1000); long finish = System.nanoTime(); long elapsed = finish - start; System.out.println("Прошло времени, нс: " + elapsed); } public static void instant() throws InterruptedException { Instant start = Instant.now(); // выполнение какой-то логики Thread.sleep(1000); Instant finish = Instant.now(); long elapsed = Duration.between(start, finish).toMillis(); System.out.println("Прошло времени, мс: " + elapsed); } public static void stopWatch() throws InterruptedException { StopWatch stopWatch = new StopWatch(); stopWatch.start(); // выполнение какой-то логики Thread.sleep(1000); stopWatch.stop(); System.out.println("Прошло времени, мс: " + stopWatch.getTime()); } }
Заключение
В данной статье мы разобрали простые методы замера времени выполнения в Java. Для простых замеров можно использовать все вышеперечисленные методы, кроме currentTimeMillis (из-за того, что он зависит от системных часов).