322

How do I calculate the time taken for the execution of a method in Java?

james.garriss
  • 12,959
  • 7
  • 83
  • 96
Renuka
  • 3,427
  • 3
  • 17
  • 5
  • 1
    lol, that is a lot of duplicates :D too bad that when you close a question you can only name one :( – IAdapter Aug 01 '10 at 20:53
  • You forgot to mention explicitly the purpose of the measurement, which might have influence on the way it should be done. Anyway it sounds like you want to do performance optimization. In that case you should definitely read about "Micro Benchmarking". While the System.nanoTime() approach is quite simple, there is no easy way, to measure program performance exactly, because it depends on so many different factors (e.g. hardware, other software running on the same system, just-in-time and hot-spot compilation, input data etc.). – user573215 Jan 07 '13 at 10:56
  • 1
    Here is a stopwatch class for java. This formats the time output as .NET's Stopwatch class http://carlosqt.blogspot.com/2011/05/stopwatch-class-for-java.html – Carlos Quintanilla Jul 22 '11 at 12:07
  • This is a Stopwatch I made, it's very simple to use. https://gist.github.com/juanmf/4147a9b7010c7b04c003 – juanmf Nov 08 '15 at 00:23

8 Answers8

316

To be more precise, I would use nanoTime() method rather than currentTimeMillis():

long startTime = System.nanoTime();
myCall(); 
long stopTime = System.nanoTime();
System.out.println(stopTime - startTime);

In Java 8 (output format is ISO-8601):

Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end)); // prints PT1M3.553S

Guava Stopwatch:

Stopwatch stopwatch = Stopwatch.createStarted();
myCall();
stopwatch.stop(); // optional
System.out.println("Time elapsed: "+ stopwatch.elapsed(TimeUnit.MILLISECONDS));
Mohammed H
  • 6,880
  • 16
  • 81
  • 127
Vitalii Fedorenko
  • 110,878
  • 29
  • 149
  • 111
  • 18
    You might want to format the result. Nanoseconds time for anything worthwhile is going to have a lot of digits. – Tom Hawtin - tackline Aug 01 '10 at 17:46
  • thanks @Vitalii Fedorenko.Is it going to be exact if the method involves lots of db transactions ? – Nagappa L M Aug 18 '15 at 05:49
  • I do not see why the number of database transactions should affect the accuracy, the only thing to keep in mind is that the time of the db query will be included in the total execution time. – Vitalii Fedorenko Aug 19 '15 at 00:18
  • Please update your answer. Guava library url and lib has changed https://google.github.io/guava/releases/19.0/api/docs/com/google/common/base/Stopwatch.html – Ako Aug 16 '16 at 23:50
  • 3
    @VitaliiFedorenko if I'm correct Instant.now()internally use System.currentTimeMillis() .. using that is not recommended – Kavindu Dodanduwa Oct 31 '16 at 05:55
  • 1
    A better way would be to run JvisualVM .Just run your method or class and start jvisualVM.Select your java process(if run locally it will list the java process).Go to sampler, monitor CPU, take a snapshot after metod finishes. and you can get time taken by each method in call tree. its buddled in jvm/jdk. – arvin_v_s Jun 21 '17 at 04:13
  • how is guava's Stopwatch better than Java's classes? – Gaurav Apr 20 '19 at 08:52
  • @VitaliiFedorenko is there any alternative like using a profiler for measuring the time? – Gaurav Oct 16 '19 at 13:29
  • For a great, concise explanation about why nanoTime is preferred, see [this](https://youtu.be/mAyW-4LeXZo?t=662) Cambridge professors lecture:) – Ferg Apr 23 '23 at 12:36
254

You can take timestamp snapshots before and after, then repeat the experiments several times to average to results. There are also profilers that can do this for you.


From "Java Platform Performance: Strategies and Tactics" book:

With System.currentTimeMillis()

class TimeTest1 {
   public static void main(String[] args) {

      long startTime = System.currentTimeMillis();

      long total = 0;
      for (int i = 0; i < 10000000; i++) {
         total += i;
      }

      long stopTime = System.currentTimeMillis();
      long elapsedTime = stopTime - startTime;
      System.out.println(elapsedTime);
   }
}

With a StopWatch class

You can use this StopWatch class, and call start() and stop before and after the method.

class TimeTest2 {
   public static void main(String[] args) {

      Stopwatch timer = new Stopwatch().start();

      long total = 0;
      for (int i = 0; i < 10000000; i++) {
         total += i;
      }

      timer.stop();
      System.out.println(timer.getElapsedTime());
   }
}

See here (archived).


NetBeans Profiler:

Application Performance Application

Performance profiles method-level CPU performance (execution time). You can choose to profile the entire application or a part of the application.

See here.

Community
  • 1
  • 1
bakkal
  • 54,350
  • 12
  • 131
  • 107
53

Check this: System.currentTimeMillis.

With this you can calculate the time of your method by doing:

long start = System.currentTimeMillis();
class.method();
long time = System.currentTimeMillis() - start;
JJD
  • 50,076
  • 60
  • 203
  • 339
31

In case you develop applications for Android you should try out the TimingLogger class.
Take a look at these articles describing the usage of the TimingLogger helper class:

drac_o
  • 427
  • 5
  • 11
JJD
  • 50,076
  • 60
  • 203
  • 339
  • Android came up with some utils like timeLogger and Textutils .. Thanks for pointing out.. :) – Mahendran Oct 11 '13 at 05:00
  • @JJD is there any profiler for it instead of using this class? – Gaurav Oct 16 '19 at 13:28
  • Android Studio has a built-in CPU profile where you see how long certain processes took. Not sure if this is what you are looking for. – JJD Oct 16 '19 at 13:35
15

You might want to think about aspect-oriented programming. You don't want to litter your code with timings. You want to be able to turn them off and on declaratively.

If you use Spring, take a look at their MethodInterceptor class.

drac_o
  • 427
  • 5
  • 11
duffymo
  • 305,152
  • 44
  • 369
  • 561
11

If you are currently writing the application, than the answer is to use System.currentTimeMillis or System.nanoTime serve the purpose as pointed by people above.

But if you have already written the code, and you don't want to change it its better to use Spring's method interceptors. So for instance your service is :

public class MyService { 
    public void doSomething() {
        for (int i = 1; i < 10000; i++) {
            System.out.println("i=" + i);
        }
    }
}

To avoid changing the service, you can write your own method interceptor:

public class ServiceMethodInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = methodInvocation.proceed();
        long duration = System.currentTimeMillis() - startTime;
        Method method = methodInvocation.getMethod();
        String methodName = method.getDeclaringClass().getName() + "." + method.getName();
        System.out.println("Method '" + methodName + "' took " + duration + " milliseconds to run");
        return null;
    }
}

Also there are open source APIs available for Java, e.g. BTrace. or Netbeans profiler as suggested above by @bakkal and @Saikikos. Thanks.

JJD
  • 50,076
  • 60
  • 203
  • 339
kinshuk4
  • 3,241
  • 3
  • 33
  • 41
5

As proposed nanoTime () is very precise on short time scales. When this precision is required you need to take care about what you really measure. Especially not to measure the nanotime call itself

long start1 = System.nanoTime();
// maybe add here a call to a return to remove call up time, too.
// Avoid optimization 
long start2 = System.nanoTime();
myCall(); 
long stop = System.nanoTime();
long diff = stop - 2*start2 + start1;

System.out.println(diff + " ns");

By the way, you will measure different values for the same call due to

  • other load on your computer (background, network, mouse movement, interrupts, task switching, threads)
  • cache fillings (cold, warm)
  • jit compiling (no optimization, performance hit due to running the compiler, performance boost due to compiler (but sometimes code with jit is slower than without!))
stefan bachert
  • 9,413
  • 4
  • 33
  • 40
1

Nanotime is in fact not even good for elapsed time because it drifts away signficantly more than currentTimeMillis. Furthermore nanotime tends to provide excessive precision at the expense of accuracy. It is therefore highly inconsistent,and needs refinement.

For any time measuring process,currentTimeMillis (though almost as bad), does better in terms of balancing accuracy and precision.

Brian
  • 13,412
  • 10
  • 56
  • 82
sarvesh
  • 31
  • 2
  • 2
    currentTimeMillis should not be used for calculating elapsed time as it's not monotonic (you might end up with negative elapsed time!). See e.g http://stackoverflow.com/questions/2978598/will-system-currenttimemillis-always-return-a-value-previous-calls – Henrik Nordvik Apr 11 '17 at 17:18