0

I'm wondering why this code returns different times:

My outputs are:

Time1: 511 Time2: 228 for N: 100000000
Time1: 509 Time2: 229 for N: 100000001
Time1: 503 Time2: 229 for N: 100000002

I have:

java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.4) (6b24-1.11.4-1ubuntu0.12.04.1)
OpenJDK Server VM (build 20.0-b12, mixed mode)
Intel® Pentium(R) CPU B960 @ 2.20GHz × 2 
Linux Ubuntu 12.04

My code looks like:

public class test {

    public static void main(String[] arg)
    {
        for(long N=100000000;N<2000000000;++N){

            long time2 = System.currentTimeMillis();
            double d = 1.0; 
            double z = 1.0/3.0;
            for(long i = 0; i < N; i++)
            {
                d = d*z;
            }
            long result2 = System.currentTimeMillis() - time2;


            long time1 = System.currentTimeMillis();
            double x = 1.0;
            double f = 1.0/3.0;
            for(long i = 0; i < N; i++)
            {
                x = x*f;
            }
            long result1 = System.currentTimeMillis() - time1;



            System.out.println("Time1: " + result1 + " Time2: " + result2 + " bigger: " + (result1 > result2) + " for N: " + N);
        }

    }
}
Nishant
  • 54,584
  • 13
  • 112
  • 127
Gelldur
  • 11,187
  • 7
  • 57
  • 68

4 Answers4

9

Benchmarking code in Java is hard.

The JVM does lots of things in the background:

  • it optimizes code on the fly,
  • compile methods after a certain number of times they are called (so methods can suddenly get faster, but compilation consumes resources, so everything might get slow for some time),
  • it can move variables outside loops if it sees fit,
  • it can even simply remove some code if it sees that it does nothing (for instance: you are calculating d, but you don't do anything with it, so why calculate it? the JVM is allowed to simply remove that code; read about "escape analysis").
  • There might also happen some garbage collection, etc.

Also, your operating system might interfere with the JVM's execution, etc.

So, the bottom line is: without studying a lot on how the JVM and your operating system works, forget about doing precise benchmarks. You can't expect to get meaningful results.

For more information, check this question and answers. It contains links to very good papers.

Community
  • 1
  • 1
Bruno Reis
  • 37,201
  • 11
  • 119
  • 156
  • Thanks for response but i only test it for fun. Because this is really strange. – Gelldur Oct 16 '12 at 18:33
  • @Gelldur: just to show you that this kind of measurement makes no sense in the JVM, running on my machine gives the exact opposite of what you are seeing: `Time1: 179 Time2: 456 bigger: false for N: 100000004`, ie, I have consistently `Time1 < Time2`. – Bruno Reis Oct 16 '12 at 23:14
1

Have you repeated this code many times? What is the medium of times you got? The times can vary for many reasons: your processes and threads are sharing the same CPU (1 or more) and other resources of your computer, for instance. You will get different values each time, and the difference will not be important.

logoff
  • 3,347
  • 5
  • 41
  • 58
0

Your system availability is not controlled by Java.

If you notice, all your results are in same range. This is the best you can expect.

If there are some other things going on even within th JVM e.g. Garbage Collection, your timings may vary little more.

Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73
0

Please remember: running an application on a modern operating system has a side effect: other applications are running there too. The operating system schedules different applications and assigns every process time slots on the CPU. Every time you execute the application it get's executed in a different order with different other processes. This influences the total execution time.

romedius
  • 775
  • 6
  • 20
  • Yes i know it but it doesn't matter when i run this code many times on my computer where system uses 0-2% of CPU. – Gelldur Oct 16 '12 at 18:35