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.
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.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.