someone
someone

Reputation: 53

Elapsed time using System.nanoTime() around several method calls delivers a lower value than the sum of of the elapsed times in each method?

I'm using System.nanoTime() to measure the time it takes to call several methods. In each of those methods I do the same to measure how long each method takes. In the end the sum of the elapsed times should be smaller than the total elapsed time, or so I thought. However, it isn't.

Example:

public static void main(String[] args){
  long startTime = System.nanoTime();
  method1();
  method2();
  method3();
  System.out.println( "Total Time: " + (System.nanoTime() - startTime) / 1000000);
}
private void method1(){
  long startTime = System.nanoTime();
  //Stuff
  System.out.println( "Method 1: " + (System.nanoTime() - startTime) / 1000000);
}
// same for all other methods

In my case I get something around 950ms for the total time, but the sum of each elapsed time is 1300ms+. Why is this?

EDIT:

Okay, to be a bit clearer, I am not getting this behaviour when writing to arrays many times (which I just did as a test). When I do this, I get pretty much exact results (+-1ms).

What I am actually doing is this:

I read two pretty huge text files into String arrays (1000 * ~2000 characters in first file, 200 * ~100 characters in the second).

I then do a whole lot of comparisons on the String array I got from reading the first file and use the results to calculate some probabilities.

EDIT2: Error on my part, I was calling methods within methods and summed up those times as well, which were already included. Without these double-times it all adds up. Thanks for clearing this up!

Upvotes: 4

Views: 11960

Answers (3)

Doug M
Doug M

Reputation: 101

Try changing your doe to something like this:

public static void main(String[] args)
{
    long elaspeTime = 0;
    elaspeTime += method1();
    elaspeTime += method2();
    elaspeTime += method3();
    System.out.println("Total Time: " + elaspeTime / 1000000);
}

private static long method1()
{
    long startTime = System.nanoTime();
    //Do some work here...
    System.out.println("Method 1: " + (System.nanoTime() - startTime) / 1000000);
    return System.nanoTime() - startTime;

}

Upvotes: 0

Cyrille Ka
Cyrille Ka

Reputation: 15533

To further investigate this thing, maybe you can print out the start and end time of each method and of the global process. Here you are just printing the time taken by each one and the total time, but you can output something like this:

Global start   : (result of System.nanoTime() here)
Method 1 Start : ...
Method 1 End   : ....
Method 2 Start : ....
Method 2 End   : ....
Method 3 Start : ....
Method 3 End   : ....
Global end     : ....

Why I suggest you to do this is the following: you expected GlobalEnd - GlobalStart to be greater than or equal to (End1-Start1) + (End2-Start2) + (End3-Start3). But this relation actually derives from the fact that if everything is sequential the following holds true:

GlobalStart <= Start1 <= End1 <= Start2 <= End2 <= Start3 <= End3 <= GlobalEnd

Isn't it?

Then what would be interesting for you is to know what is not true in this list of inequations. This could possibly give you some insight.

Upvotes: 5

Doug M
Doug M

Reputation: 101

I see nothing wrong with your code. In my testing I got the correct elapsed time from your code.

Here is my output:

Method 1: 600 Method 2: 500 Method 3: 10 Total Time: 1110 BUILD SUCCESSFUL (total time: 2 seconds)

Upvotes: 1

Related Questions