0

I need to get the execution time for a function in Java. I am aware of two methods I can use: currentTimeMillis(); and nanoTime(); But I have learned that currentTimeMillis(); is more accurate if I need the wall-clock time (i.e, as if I am measuring from the wall-clock how much time the execution took. Not the processing time).

But currentTimeMillis(); can not give me small fraction number. For example, if the execution time is less than 1 millisecond, it returns 0. I need the time even if it is less than 1, say, 0.05 ms. This is a simple example when the method returns 0.

long startTime=System.currentTimeMillis();
for(int x=0; x<10;x++)
{
    System.out.println("-");
}

long execTime=System.currentTimeMillis() - startTime;

Even if it returns time, it return it as 30 or 40. But, I need a more precise number, say, 30.00012. Also, the method return type is long but I changed it to double as I want the number in a floating point, is there any harm in this? Can you tell me to the proper way by which I can measure my java method execution wall-clock time in small fraction number (e.g. not 8.0 but 8.287335)

Wiliam A
  • 457
  • 3
  • 7
  • 10
  • 1
    Have you thought about using a profiler? – Will C. Jan 05 '13 at 15:51
  • 1
    "but I changed it to `double` as I want the number in a floating point, is there any harm in this?" You get rounding effects if the returned number of milli- or nanoseconds is larger than `2^53`, but mostly, it's just pointless because the timers return integer values. – Daniel Fischer Jan 05 '13 at 15:53

3 Answers3

6

I am aware of two methods I can use: currentTimeMillis() and nanoTime(). But I have learned that currentTimeMillis() is more accurate if I need the wall-clock time (i.e, as if I am measuring from the wall-clock how much time the execution took. Not the processing time).

That's only partly accurate.

Both functions return wall-clock time, and not CPU time.

The difference, other than precision, is that currentTimeMillis() is relative to a well-known point in time, whereas nanoTime() is relative to some arbitrary point in time. This means that you can't easily translate the result of nanoTime() into a timestamp that you and I would understand.

You can still use it to measure wall-clock intervals: just call nanoTime() twice and take the difference. That's pretty much what it's been designed for.

Finally, if you're using this to profile some code, read How do I write a correct micro-benchmark in Java? There are lots of subtleties.

Community
  • 1
  • 1
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Can you check: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime%28%29. They say: `and is not related to any other notion of system or wall-clock time`. Am I misunderstanding something? – Wiliam A Jan 05 '13 at 15:58
  • 2
    @WiliamA The document you reference says "can only be used to measure elapsed time". You are trying to measure elapsed time, so there is no problem. The issue is that nanoTime results do not relate to date. If you start one long running job on Wednesday, and another job on Thursday, a nanoTime call in the Wednesday job may have a bigger result than a nanoTime call that happened later in the Thursday job. – Patricia Shanahan Jan 05 '13 at 16:02
  • 1
    @WiliamA: I think the confusion is terminological. `nanoTime()`'s elapsed second is the same second as yours & mine. What is not defined is the *origin* from which `nanoTime()` starts counting. You can still subtract two `nanoTime()` values and get a meaningful result. – NPE Jan 05 '13 at 16:02
1

Use System.nanoTime() it has precision of nanosecond.

Shivam
  • 2,134
  • 1
  • 18
  • 28
0

Although you can and should use nanoTime to get the most precise available execution time for a block of code. However, you should use it with caution, because there are many outside issues that can affect execution time.

For example, any time a method is called without having run recently, there will be overhead for getting it into cache. Depending on what else is in the same page, there may even be a disk read to get it into memory.

A JVM may treat a method differently if it only runs once compared to running it many times.

Generally, when you care about microseconds it is because the thing you are measuring is going to run many times in a job or transaction. To get an accurate measure of that you need to measure across many calls. Doing so also reduces the impact of the overhead time for calling nanoTime.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75