Зачастую требуется узнать, сколько времени выполняется тот или иной код. Иногда требуется замерить время выполнения метода или какой-то задачи. В данной статье мы расскажем вам принципы замера времени в 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 (из-за того, что он зависит от системных часов).

Как замерить время выполнения