Java
Time Measurement
Programming
Coding Techniques
Software Development

How do I measure time elapsed in Java?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

To measure elapsed time in Java, the usual tool is System.nanoTime(), not System.currentTimeMillis(). The key distinction is that elapsed-time measurement needs a monotonic clock, while wall-clock timestamps are about calendar time and can move because of clock adjustments.

Use System.nanoTime() for Elapsed Time

For timing how long code takes to run, System.nanoTime() is the standard choice.

java
1long start = System.nanoTime();
2
3// code you want to measure
4doWork();
5
6long end = System.nanoTime();
7long elapsedNanos = end - start;
8
9System.out.println("Elapsed time: " + elapsedNanos + " ns");

Despite the name, the returned value is not a wall-clock timestamp. It is a monotonic time source intended for measuring intervals. That is exactly why it is better for elapsed time than currentTimeMillis().

Why System.currentTimeMillis() Is Not Ideal

System.currentTimeMillis() returns wall-clock time since the Unix epoch.

java
1long start = System.currentTimeMillis();
2doWork();
3long end = System.currentTimeMillis();
4
5System.out.println("Elapsed ms: " + (end - start));

This can work for rough timing, but it has two problems:

  • lower effective resolution on many systems
  • sensitivity to system clock changes

If the OS clock is adjusted while your code runs, the elapsed calculation may be misleading. That is why currentTimeMillis() is for timestamps, not serious duration measurement.

Convert Nanoseconds to Readable Units

Raw nanoseconds are precise, but not always convenient to display directly.

java
1long start = System.nanoTime();
2doWork();
3long elapsedNanos = System.nanoTime() - start;
4
5double elapsedMillis = elapsedNanos / 1_000_000.0;
6System.out.println("Elapsed ms: " + elapsedMillis);

This is often enough for logging and debugging. For user-facing or report-style code, wrapping the interval in Duration can be clearer.

Instant and Duration for Readability

If readability matters more than low-level timing detail, java.time can be a good fit.

java
1import java.time.Duration;
2import java.time.Instant;
3
4Instant start = Instant.now();
5doWork();
6Instant end = Instant.now();
7
8Duration elapsed = Duration.between(start, end);
9System.out.println("Elapsed ms: " + elapsed.toMillis());

This is pleasant to read, but remember that Instant.now() is still tied to the system clock rather than the monotonic timer that powers nanoTime(). For benchmarking or tight performance measurement, nanoTime() remains the safer default.

Timing Repeated Operations

One run is often noisy because of JIT compilation, cache effects, class loading, and background system activity. If you want a more meaningful measurement, repeat the operation and aggregate the results.

java
1long totalNanos = 0;
2
3for (int i = 0; i < 100; i++) {
4    long start = System.nanoTime();
5    doWork();
6    totalNanos += System.nanoTime() - start;
7}
8
9System.out.println("Average ns: " + (totalNanos / 100));

This is still only a rough benchmark, but it is better than trusting one timing sample.

For Real Benchmarking, Use JMH

If you are benchmarking performance seriously, use JMH instead of handwritten loops. JMH handles warm-up, dead-code elimination risks, and measurement rigor much better than ad hoc timing snippets.

Handwritten timing is fine for diagnostics, logs, and rough comparisons. It is not a replacement for a real microbenchmark framework when performance claims matter.

Common Pitfalls

The most common mistake is using System.currentTimeMillis() for elapsed time and assuming the result is stable and precise. Another is taking a single timing sample and treating it as authoritative, even though JIT warm-up and other runtime effects can dominate short measurements. Developers also benchmark tiny methods without protecting against dead-code elimination or optimizer artifacts, which makes the numbers look more certain than they really are.

Summary

  • Use System.nanoTime() for elapsed-time measurement.
  • Use System.currentTimeMillis() for wall-clock timestamps, not precise duration timing.
  • Convert nanoseconds into milliseconds or other units for readable output.
  • 'Instant and Duration are readable, but they are not a replacement for a monotonic timer in benchmarks.'
  • Use JMH when you need serious performance measurements rather than rough diagnostics.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions