⏱ Измеряем время выполнения кода в Java с помощью StopWatch
Вступление
Чтобы написать хорошее приложение, важно измерять время выполнения кода. Так вы сможете планировать ваши дальнейшие действия, учитывая время.
В многопоточных системах также полезно измерять время выполнения отдельных потоков (Thread) или асинхронных задач.
Поскольку в Java нет встроенного способа измерения времени выполнения строчного кода, мы использовали инструмент StopWatch.
В этом уроке мы рассмотрим, как измерить время выполнения кода на Java с помощью StopWatch.
Что такое StopWatch?
StopWatch – это служебный класс, находящийся в пакете util. У него очень простой API, он даёт нам возможность определять время выполнения отдельных задач, групп задач и общее время выполнения программы.
Этот класс обычно используется для проверки производительности кода на этапе разработки.
Примечание: StopWatch непотокобезопасен.
Он отслеживает время в наносекундах, полагаясь на System.nanoTime().
Измеряем время выполнения кода с помощью StopWatch
Секундомер относится к базовому пакету утилит Spring:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
Также он есть в spring-boot-starter-web:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
API StopWatch сводится к созданию экземпляра и вызову start() и stop(): так он синхронизирует код с реальным секундомером. При синхронизации вы также можете указать строку, которая будет использоваться в качестве имени или аннотации для связанной задачи. Это помогает дифференцировать их результаты.
Задача – это период между вызовом start() и stop(). Для каждой задачи, созданной при запуске StopWatch, её имя и время выполнения сохраняются в экземпляре TaskInfo и добавляются в список задач.
Создадим задачу с именем и измерим время выполнения части кода:
StopWatch timeMeasure = new StopWatch();
timeMeasure.start("Task 1");
Thread.sleep(1000);
timeMeasure.stop();
System.out.println("Last task time in Millis: "
+ timeMeasure.getLastTaskMillis());
Результат:
Last task time in Millis: 1009
Вы можете получить доступ к сумме всех задач с помощью функций getTotalTimeSeconds(), getTotalTimeMillis() и getTotalTimeNanos().
Вы также можете получить доступ к последней задаче StopWatch через getLastTaskInfo(), который выводит экземпляр TaskInfo. Этот экземпляр содержит информацию о последней задаче, например, имя и сколько времени она заняла в секундах, миллисекундах и наносекундах:
StopWatch stopWatch = new StopWatch();
stopWatch.start("Task 1");
Thread.sleep(1000);
stopWatch.stop();
System.out.println(stopWatch.getLastTaskInfo().getTaskName());
System.out.println(stopWatch.getLastTaskInfo().getTimeMillis());
Результат:
Task 1
1008
При решении нескольких задач удобно использовать метод prettyPrint(), который печатает все записи в табличном виде с простым форматированием:
StopWatch stopWatch = new StopWatch("Measure Code Execution");
stopWatch.start("1. Task");
Thread.sleep(2000);
stopWatch.stop();
stopWatch.start("2. Task");
Thread.sleep(5000);
stopWatch.stop();
stopWatch.start("3. Task");
Thread.sleep(3000);
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
Вывод:
StopWatch 'Measure Code Execution': running time = 10012348500 ns
---------------------------------------------
ns % Task name
---------------------------------------------
2002729600 020% 1. Task
5006985700 050% 2. Task
3002633200 030% 3. Task
Примечание: если мы используем секундомер для измерения времени выполнения кода для большого количества интервалов (порядка сотен тысяч или миллионов) – список TaskInfo займёт значительную часть вашей памяти. Вы можете отключить его так:
stopWatch.setKeepTaskList(false);
Заключение
В этом уроке мы рассмотрели класс утилиты StopWatch – ответ Spring на отсутствие инструментов измерения времени в Java.