Measuring Execution Time of Java Methods

There are 2 ways to measure execution time of Java methods.

Wall Clock Time Vs. CPU Time

  1. Wall Clock Time: Time that you actually wait for the method to complete. This metric is useful in measuring how fast a user perceives your method to be. For desktop apps and mobile apps, this measure is rarely accurate because we don’t know what other programs the user might be running in parallel when they are using our app. But this is very useful if you are measuring performance on server applications. Because they run on our server where we can control the capabilities and load from other programs. Wall clock time is what we measure in typical performance tests of web applications.
  2. CPU Time: Time spent by the CPU executing the method. Since the CPU is shared by all processes running on a computer, this metric shows you how much of the resource your program is using – or in other words, for how much time, the CPU core was kept active by your program. In an ideal world, this would be exactly the same if you run the same code again and again, but our world is more ideal than ideal – both the JVM and the OS, execute code in quite complicated ways to optimise system usage. So there still might be differences between each execution but much less than wall clock time.
Photo by Andrew Seaman on Unsplash

Source Code

You can get the source code for this article on GitHub – https://github.com/heppydepe/measuring-execution-time-of-java-methods/tree/v1.0

The Sample Class

We will use the following RandomNumbers class and measure it’s execution time. This is a neat little class for demonstrating time measurement – we can test the object creation because it creates 100 random numbers, we can test IO operation that happens when you execute writeToFile(), and you can test string conversion through the toString() method.

package com.codecreek.methodbenchmark;

import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class RandomNumbers {
    private List<Integer> list;

    public RandomNumbers() {
        Random rand = new Random();
        list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            list.add(rand.nextInt());
        }
    }

    public void writeToFile() {
        FileWriter fileWriter = new FileWriter("output.txt");
        fileWriter.write(this.toString());
        fileWriter.close();
    }

    public String toString() {
        return list.toString();
    }
}

Measuring Wall Clock Time

Wall Clock Time can be measured using the System.nanoTime() method. Capture the elapsed time when the execution starts, then capture it again when the execution ends. There are a dozen ways of capturing system time, but I like the simple nanoTime(). For some other ways you can refer this StackOverflow answer.

try {
    for (int i = 0; i < iterations; i++) {
        startTime = System.nanoTime();
        randomNumbers.writeToFile();
        endTime = System.nanoTime();
        if (i >= skipFirst) {
            measureList.add(endTime - startTime);
        }
    }
} catch (IOException ex) {
    ex.printStackTrace();
}

System.out.println("Wall Clock Time:\t" + measureList);

Measuring CPU Time

CPU Time can be measured using the ThreadMXBean. To get an instance, we use ManagementFactory.getThreadMXBean() and then it has a method getCurrentThreadCpuTime() to get elapsed time of the current thread. Again, there are other ways of doing this, but for this article I’m just keeping to the simplest ways. You don’t need external dependencies for ThreadMXBean.

ThreadMXBean tmb = ManagementFactory.getThreadMXBean();
try {
    for (int i = 0; i < iterations; i++) {
        startTime = tmb.getCurrentThreadCpuTime();
        randomNumbers.writeToFile();
        endTime = tmb.getCurrentThreadCpuTime();
        if (i >= skipFirst) {
            measureList.add(endTime - startTime);
        }
    }
} catch (IOException ex) {
    ex.printStackTrace();
}

System.out.println("CPU Time:\t" + measureList);

Output

I ran the code on my computer and this is what I got –

Wall Clock Time:
        Stats{count=10000, mean=278124.58609999955, populationStandardDeviation=368752.52698052896, min=111579.0, max=1.258139E7}

CPU Time:
        Stats{count=10000, mean=210671.20000000033, populationStandardDeviation=86977.8137835161, min=110000.0, max=1794000.0}

I used the Stats functions from Google Guava library. Even in this relatively naive test, I could notice that the wall clock time has much greater variance than CPU time.

But I do have to reiterate. This test is practically good for my use case. But might not be for others. Because I haven’t considered what optimisations my JVM and my OS may have done while executing the code. This is more of a ‘getting-started’ kind of article. For more serious benchmarking it’s better to use tools like JMH or Google Caliper .

Author: heppydepe

I'm Heppy Depe. (Read "Heppy" like "Peppy" and "Depe" like "DayPay"). Writing under a pseudonym because .. I dunno I just felt like writing under a pseudonym. I'm still trying to find the perfect picture of a fish to set as my profile photo.

One thought on “Measuring Execution Time of Java Methods”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s