Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's a clean way to time code execution in Java?

It can be handy to time code execution so you know how long things take. However, I find the common way this is done sloppy since it's supposed to have the same indentation, which makes it harder to read what's actually being timed.

long start = System.nanoTime();

// The code you want to time

long end = System.nanoTime();
System.out.printf("That took: %d ms.%n", TimeUnit.NANOSECONDS.toMillis(end - start));

An attempt

I came up with the following, it looks way better, there are a few advantages & disadvantages:

Advantages:

  • It's clear what's being timed because of the indentation
  • It will automatically print how long something took after code finishes

Disadvantages:

  • This is not the way AutoClosable is supposed to be used (pretty sure)
  • It creates a new instance of TimeCode which isn't good
  • Variables declared within the try block are not accessible outside of it

It can be used like this:

 try (TimeCode t = new TimeCode()) {
     // The stuff you want to time
 }

The code which makes this possible is:

class TimeCode implements AutoCloseable {

    private long startTime;

    public TimeCode() {
        this.startTime = System.nanoTime();
    }

    @Override
    public void close() throws Exception {
        long endTime = System.nanoTime();
        System.out.printf("That took: %d ms%n",
                TimeUnit.NANOSECONDS.toMillis(endTime - this.startTime));
    }

}

The question

My question is:

  • Is my method actually as bad as I think it is
  • Is there a better way to time code execution in Java where you can clearly see what's being timed, or will I just have to settle for something like my first code block.
like image 677
Mark Avatar asked Oct 23 '18 10:10

Mark


People also ask

How do you make a Java program wait for some time?

The easiest way to delay a java program is by using Thread. sleep() method. The sleep() method is present in the Thread class. It simply pauses the current thread to sleep for a specific time.

How do you stop a time execution in Java?

Using a Loop long start = System. currentTimeMillis(); long end = start + 30 * 1000; while (System. currentTimeMillis() < end) { // Some expensive operation on the item. } Here, the loop will break if the time has surpassed the limit of 30 seconds.


2 Answers

You solution is just fine.

A less expressive way would be to wrap your code to be timed in a lambda.

public void timeCode(Runnable code) {
    ...
    try {
        code.run();
    } catch ...
    }
    ...
}

timeCode(() -> { ...code to time... });

You would probably like to catch the checked exceptions and pass them to some runtime exception or whatever.

like image 127
Joop Eggen Avatar answered Nov 05 '22 07:11

Joop Eggen


You method is great as-is. We use something similar professionally but written in C#.

One thing that I would potentially add, is proper logging support, so that you can toggle those performance numbers, or have them at a debug or info level.

Additional improvements that I would be considering, is creating some static application state, (abusing thread locals) so that you can nest these sections, and have summary breakdowns.

See https://github.com/aikar/minecraft-timings for a library that does this for minecraft modding (written in java).

like image 35
Ryan Leach Avatar answered Nov 05 '22 06:11

Ryan Leach