Java вывести время выполнения

Calculate Elapsed/Execution Time in Java

Wonder on how long your function is get executed? How you measure elapsed time in Java? In this article, we’ll explore several ways to measure elapsed time.

System.currentTimeMillis()

  • static long currentTimeMillis(): Part of Class System, returns the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
import java.util.concurrent.TimeUnit; public class ElapsedTimeCurrentTimeMillis < static void doSomething() < try < // Sleep 3 seconds TimeUnit.SECONDS.sleep(3); >catch (InterruptedException ex) < System.out.println("InterruptedException occured: " + ex.getMessage()); >> public static void main(String[] args) < long startTime = System.currentTimeMillis(); doSomething(); long endTime = System.currentTimeMillis(); // calculate time difference long timeDiff = endTime - startTime; System.out.println("Elapsed time in milliseconds: " + timeDiff); >> 
Elapsed time in milliseconds: 3002

Be aware that System.currentTimeMillis() has a pretty bad resolution:

System.nanoTime()

  • static long nanoTime(): Part of Class System, returns the current value of the running Java Virtual Machine’s high-resolution time source, in nanoseconds.

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time.

import java.util.concurrent.TimeUnit; public class ElapsedTimeNanoTime < static void doSomething() < // Sleep 3 seconds - purposely truncated >public static void main(String[] args) < long startTime = System.nanoTime(); doSomething(); long endTime = System.nanoTime(); // calculate time difference long timeDiff = TimeUnit.NANOSECONDS.toMillis(endTime - startTime); System.out.println("Elapsed time in milliseconds: " + timeDiff); >> 
Elapsed time in milliseconds: 3002

System.nanoTime() has a better resolution:

  • it should never be worse than System.currentTimeMillis()
  • depending on the hardware and OS it can deliver accuracy in the microsecond range
Читайте также:  Html and css design tutorials

Because of those reasons, this is the most recommended solution to measure elapsed time in Java.

Date.getTime()

  • long getTime(): Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
import java.util.Date; import java.util.concurrent.TimeUnit; public class ElapsedTimeDateGetTime < static void doSomething() < // Sleep 3 seconds - purposely truncated >public static void main(String[] args) < long startTime = new Date().getTime(); doSomething(); long endTime = new Date().getTime(); // calculate time difference long timeDiff = endTime - startTime; System.out.println("Elapsed time in milliseconds: " + timeDiff); >> 
Elapsed time in milliseconds: 3002

Java 8 — Using Instant and Duration

  • Instant: Represents an instant in time on the time line. In Java 8 the Instant class represents an instant in time represented by a number of seconds and a number of nanoseconds since Jan. 1st 1970.
  • Duration: Represents a duration of time, for instance the time between two instants. Like the Instant class a Duration represents its time as a number of seconds and nanoseconds.
import java.time.Duration; import java.time.Instant; import java.util.concurrent.TimeUnit; public class ElapsedTimeInstantDuration < static void doSomething() < // Sleep 3 seconds - purposely truncated >public static void main(String[] args) < Instant instantStart = Instant.now(); long startTime = instantStart.toEpochMilli(); doSomething(); Instant instantEnd = Instant.now(); long endTime = instantEnd.toEpochMilli(); // calculate time difference long timeDiff = endTime - startTime; System.out.println("toEpochMilli - Elapsed time in ms: " + timeDiff); long timeElapsed = Duration.between(instantStart, instantEnd).toMillis(); System.out.println("Duration - Elapsed time in ms: " + timeElapsed); >> 
toEpochMilli - Elapsed time in ms: 3001 Duration - Elapsed time in ms: 3001

Joda-Time Instant and Duration

  • Instant: Represents an exact point in time in milliseconds from the Java epoch of 1970-01-01T00:00:00Z
  • Duration: Represents the duration in milliseconds between 2 points in time

You need to add Joda-Time dependency, as example if you are using maven:

import java.util.concurrent.TimeUnit; import org.joda.time.Duration; import org.joda.time.Instant; public class ElapsedTimeJodaInstantDuration < static void doSomething() < // Sleep 3 seconds - purposely truncated >public static void main(String[] args) < Instant instantStart = Instant.now(); long startTime = instantStart.getMillis(); doSomething(); Instant instantEnd = Instant.now(); long endTime = instantEnd.getMillis(); // calculate time difference long timeDiff = endTime - startTime; System.out.println("getMillis - Elapsed time in ms: " + timeDiff); long timeElapsed = new Duration(instantStart, instantEnd).getMillis(); System.out.println("Duration - Elapsed time in ms: " + timeElapsed); >> 
getMillis - Elapsed time in ms: 3001 Duration - Elapsed time in ms: 3001

As rule of thumb, if your Java version is Java 8 and above, you should Date/Time Standard Java Library instead of using Joda-Time library.

Читайте также:  Css background image gradient opacity

Many open source Java libraries like Apache Commons Lang, Google Guava and Spring also provides «StopWatch» utility class which can be used to measure elapsed time in Java. StopWatch improves readability to minimize calculation error while calculating elapsed execution time but beware that StopWatch is not thread safe and should not be shared in multi-threading environment.

Apache Commons Lang Stopwatch

StopWatch provides a convenient API for timings.

To start the watch, call start() or createStarted(). At this point you can:

  • split() the watch to get the time whilst the watch continues in the background. unsplit() will remove the effect of the split. At this point, these three options are available again.
  • suspend() the watch to pause it. resume() allows the watch to continue. Any time between the suspend and resume will not be counted in the total. At this point, these three options are available again.
  • stop() the watch to complete the timing session.

It is intended that the output methods toString() and getTime() should only be called after stop, split or suspend, however a suitable result will be returned at other points.

This class is not thread-safe

You need to add dependency for Apache Commons Lang, like if you using maven:

  org.apache.commons commons-lang3 3.8.1  
import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.time.StopWatch; public class ElapsedTimeApacheStopWatch < static void doSomething() < try < // Sleep 2 seconds TimeUnit.SECONDS.sleep(2); >catch (InterruptedException ex) < System.out.println("InterruptedException occured: " + ex.getMessage()); >> public static void main(String[] args) < StopWatch sWatch = new StopWatch(); sWatch.start(); doSomething(); sWatch.suspend(); doSomething(); sWatch.resume(); doSomething(); sWatch.stop(); System.out.println("Elapsed time in milliseconds: " + sWatch.getTime()); >> 
Elapsed time in milliseconds: 4001

Google Guava StopWatch

We can also measure elapsed time using Guava’s Stopwatch. Stopwatch measures elapsed time in nanoseconds. It is useful to measure elapsed time using this class instead of direct calls to System.nanoTime() for a few reasons:

  • An alternate time source can be substituted, for testing or performance reasons.
  • As documented by nanoTime, the value returned has no absolute meaning, and can only be interpreted as relative to another timestamp returned by nanoTime at a different time. Stopwatch is a more effective abstraction because it exposes only these relative values, not the absolute ones.

Note: This class is not thread-safe.

Add maven dependency for Guava:

  com.google.guava guava 27.0.1-jre  
import com.google.common.base.Stopwatch; import java.time.Duration; import java.util.concurrent.TimeUnit; public class ElapsedTimeGuavaStopwatch < static void doSomething() < // Sleep 3 seconds - purposely truncated >public static void main(String[] args) < Stopwatch swatch = Stopwatch.createStarted(); doSomething(); swatch.stop(); Duration duration = swatch.elapsed(); System.out.println("Elapsed time in milliseconds: " + duration.toMillis()); >> 
Elapsed time in milliseconds: 3001

Or, if you still using Java 7, the program need to change a bit. First, we need to «downgrade» Guava version

And change the elapsed(. ) function to return instead:

Stopwatch swatch = Stopwatch.createStarted(); doSomething(); swatch.stop(); long duration = swatch.elapsed(TimeUnit.MILLISECONDS); System.out.println("Elapsed time in milliseconds: " + duration); 

Spring StopWatch

StopWatch allowing for timing of a number of tasks, exposing total running time and running time for each named task. Conceals use of System.currentTimeMillis(), improving the readability of application code and reducing the likelihood of calculation errors.

Note that this object is not designed to be thread-safe and does not use synchronization.

This class is normally used to verify performance during proof-of-concepts and in development, rather than as part of production applications.

Add dependency for Spring Core:

  org.springframework spring-core 5.1.2.RELEASE  
import java.util.concurrent.TimeUnit; import org.springframework.util.StopWatch; public class ElapsedTimeSpringStopWatch < static void doSomething() < // Sleep 2 seconds - purposely truncated >public static void main(String[] args) < StopWatch sWatch = new StopWatch("Spring StopWatch Test"); sWatch.start("Task #1"); doSomething(); sWatch.stop(); sWatch.start("Task #2"); doSomething(); sWatch.stop(); // getTotalTimeMillis(): Return the total time in milliseconds for all tasks. System.out.println("Elapsed time in milliseconds: " + sWatch.getTotalTimeMillis()); // prettyPrint(): Return a string with a table describing all tasks performed. System.out.println("Pretty Print: " + sWatch.prettyPrint()); // shortSummary(): Return a short description of the total running time. System.out.println("Short Summary: " + sWatch.shortSummary()); // getTaskCount(): Return the number of tasks timed. System.out.println("Total Task Count: " + sWatch.getTaskCount()); // getLastTaskName(): Return the name of the last task. System.out.println("Last Task Name: " + sWatch.getLastTaskName()); >> 
Elapsed time in milliseconds: 4002 Pretty Print: StopWatch 'Spring StopWatch Test': running time (millis) = 4002 ----------------------------------------- ms % Task name ----------------------------------------- 02002 050% Task #1 02000 050% Task #2 Short Summary: StopWatch 'Spring StopWatch Test': running time (millis) = 4002 Total Task Count: 2 Last Task Name: Task #2

What I like here is, Spring StopWatch provides prettyPrint() to return a string with a table describing all tasks performed, which is can be handy in test environment.

Or, if you still using Java 7, we also need to «downgrade» Spring version

  org.springframework spring-core 4.3.25.RELEASE  

And the program above will able to run without any change. Only when you try to download the library in maven central, you may encounter error: Received fatal alert: protocol_version

You need to enable TLS 1.2 protocol with Java property in the command line:

mvn -Dhttps.protocols=TLSv1.2 install

Conclusion

There are standard Java classes and external packages that provide functionality that provides many ways to measure elapsed time in Java:

  • Simple measurement, using System.currentTimeMillis() or System.nanoTime() or Date.getTime().
  • Java 8, using Instant and Duration.
  • If using Joda-Time, you also can use Instant and Duration from the library. Use Joda-Time if your Java version is prior to Java 8.
  • Using «StopWatch» utilility from Apache Commons Lang, Guava, or Spring

The most recommended way is to use System.nanoTime(). Guava’s StopWatch is useful to measure elapsed time instead of direct calls to System.nanoTime().

However, that for proper benchmarking, simple time measurement (event manual measurement) is not sufficient. You need more proper tools or framework for benchmarking.

Liked this Tutorial? Share it on Social media!

Источник

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

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

 org.apache.commons commons-lang3 3.9 

Теперь создадим экземпляр 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 (из-за того, что он зависит от системных часов).

Источник

Оцените статью