Backend Development 9 min read

Various Methods for Measuring Code Execution Time in Java

This article introduces four approaches—simple time‑difference calculation, StopWatch‑like utilities, functional interfaces, and AutoCloseable—to accurately measure arbitrary code segment durations in Java, providing code examples and discussing their advantages and trade‑offs.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Various Methods for Measuring Code Execution Time in Java

Measuring the execution time of code blocks is a common requirement in Java development, especially when identifying performance bottlenecks. The article discusses how to perform timing for arbitrary code segments, not limited to whole methods, and why AOP cannot satisfy this need.

1. Conventional Methods

1.1 Time Difference Calculation

The simplest way is to record the start time and end time, then compute the difference.

public class TimeDiffTest {
    public static void main(String[] args) throws InterruptedException {
        final long startMs = TimeUtils.nowMs();
        TimeUnit.SECONDS.sleep(5); // simulate business code
        System.out.println("timeCost: " + TimeUtils.diffMs(startMs));
    }
}

class TimeUtils {
    /** @return current milliseconds */
    public static long nowMs() {
        return System.currentTimeMillis();
    }
    /** @param startMillis start milliseconds */
    public static long diffMs(long startMillis) {
        return diffMs(startMillis, nowMs());
    }
    private static long diffMs(long start, long end) {
        return end - start;
    }
}

This method is easy to understand but intrusive to the business logic.

1.2 StopWatch‑like Utility

Many frameworks provide a StopWatch implementation. The article presents a custom TraceWatch class inspired by Spring's StopWatch .

public class TraceWatchTest {
    public static void main(String[] args) throws InterruptedException {
        TraceWatch traceWatch = new TraceWatch();
        traceWatch.start("function1");
        TimeUnit.SECONDS.sleep(1);
        traceWatch.stop();
        traceWatch.start("function2");
        TimeUnit.SECONDS.sleep(1);
        traceWatch.stop();
        traceWatch.record("function1", 1);
        System.out.println(JSON.toJSONString(traceWatch.getTaskMap()));
    }
}

public class TraceWatch {
    private long startMs;
    private String currentTaskName;
    private final Map
> taskMap = new HashMap<>();
    public void start(String taskName) { /* ... */ }
    public void stop() { /* ... */ }
    public void record(String taskName, Object data) { /* ... */ }
    @Getter @AllArgsConstructor
    public static final class TaskInfo {
        private final String taskName;
        private final Object data;
    }
}

The approach reduces code clutter compared to raw time‑difference calculation.

2. Advanced Methods

2.1 Using Functional Interfaces (Function)

Java 8's java.util.function package allows wrapping a code block with additional logic. The article provides TraceHolder utilities that accept a Supplier (for return values) or an IntConsumer (for void methods).

public class TraceHolder {
    public static
T run(TraceWatch traceWatch, String taskName, Supplier
supplier) {
        try {
            traceWatch.start(taskName);
            return supplier.get();
        } finally {
            traceWatch.stop();
        }
    }
    public static void run(TraceWatch traceWatch, String taskName, IntConsumer function) {
        try {
            traceWatch.start(taskName);
            function.accept(0);
        } finally {
            traceWatch.stop();
        }
    }
}

These helpers keep the timing logic separate from business code while preserving readability.

2.2 Using AutoCloseable

Java 7's try‑with‑resources can automatically stop timing when the resource is closed. By making TraceWatch implement AutoCloseable and returning this from start() , the timing block becomes concise.

public class TraceWatch implements AutoCloseable {
    public TraceWatch start(String taskName) { /* set start time */ return this; }
    @Override
    public void close() { this.stop(); }
}

public class AutoCloseableTest {
    public static void main(String[] args) throws Exception {
        TraceWatch traceWatch = new TraceWatch();
        try (TraceWatch ignored = traceWatch.start("function1")) {
            TimeUnit.SECONDS.sleep(1);
        }
        try (TraceWatch ignored = traceWatch.start("function2")) {
            TimeUnit.SECONDS.sleep(1);
        }
        System.out.println(JSON.toJSONString(traceWatch.getTaskMap()));
    }
}

This pattern further reduces boilerplate and guarantees that timing stops even if an exception occurs.

3. Summary

The article enumerates four ways to measure code execution time in Java: simple time‑difference calculation, a StopWatch‑style utility, functional‑interface wrappers, and AutoCloseable‑based timing. Each method balances simplicity, elegance, and intrusiveness, and developers can choose the one that best fits their project.

Javaperformancebackend developmentCode ProfilingutilitiesTiming
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.