7

I have a simple java program, and I want to know the time difference between some set of operations. For this question the details are not important, but let us take the following scenario.

long beginTime = System.currentTimeMillis();

//Some operations. Let us asssume some database operations etc. which are time consuming.

//

long endTime = System.currentTimeMillis();

long difference = endTime - beginTime;

When the code is run on a machine, how reliable will the difference be?

Let us say, that the processor starts executing some instructions from my code, then gives context to another process, which executes for some time, and then comes back to execute instructions related to this java process.

So, the time difference should depend on the current state of my machine, i.e. how many processes are running etc? So, in profiling time it takes for some operations to run, is this mechanism not reliable?

icza
  • 389,944
  • 63
  • 907
  • 827
Sumeet Khullar
  • 463
  • 1
  • 4
  • 12
  • Performing the operation 3-4 times and averaging out the results should give you a fair estimate. – Manish Oct 25 '12 at 05:57

2 Answers2

14

The granularity of System.currentTimeMillis() depends on the implementation and on the Operating system and is usually around 10 ms.

Instead use the System.nanoTime() which returns the current value of the most precise available system timer, in nanoseconds. Note that you can only use this to calculate elapsed time, you cannot use its value as an absolute time.

Example:

long startTime = System.nanoTime();
// do something you want to measure
long elapsedTimeNs = System.nanoTime() - startTime;
icza
  • 389,944
  • 63
  • 907
  • 827
  • Thanks for your answer. The granularity is important, but what I am specifically interested in understanding is, how does my current system state, and process interleaving effect this time. – Sumeet Khullar Oct 25 '12 at 05:59
  • 2
    Timers measure external ("wall") time. If you want repeatable results run your tests with nothing else competing for resources. – Jim Garrison Oct 25 '12 at 06:01
  • Yes, current system load and other processes might indeed influence the result. The longer your measured code takes to execute, the more it will be influenced. For example if your code executes only a couple of primitive operations (like adding integers), most likely the thread execution will not be suspended. If your code calculates sine values of thousands of numbers in a cycle, the chances are much higher the thread will get suspended to allow other processes to run when the system is overloaded. – icza Oct 25 '12 at 06:04
  • I've seen System.currentTimeMillis be off by as much as 100ms compared to nanoTime(). Don't use currentTimeMillis() to measure any kind of performance. – Ryan Shillington Nov 04 '13 at 16:43
2

I think your code will do just fine as same is used in several projects. I don't think that if your code calls some other database process etc then it has any effect on your time. It should work fine in that case too.

Ex.

Main Process Started
long beginTime = System.currentTimeMillis();
.
.
.
Called another process (DB or command etc) -> (Another Process start)
                                               .
<Now in this time main process is waiting>     .
                                               .
                                               .
Returned from process                      <- (Another Process end)
.
.
long endTime = System.currentTimeMillis();
long difference = endTime - beginTime;

Now this difference will be total time taken for main process including time taken by another process. THis timing is in reference to the machine of main process & that is fine.

Ravi K
  • 976
  • 7
  • 9