views:

93

answers:

4

I'm puzzled with this.

In my machine

  • Direct calculation: 375 ms
  • Method calculation: 3594 ms, about TEN times SLOWER
  • If I place the method calulation BEFORE the direct calculation, both times are SIMILAR.

Woud you check it in your machine?

class Test {
    static long COUNT = 50000 * 10000;
    private static long BEFORE;

    /*--------METHOD---------*/
    public static final double hypotenuse(double a, double b) {
        return Math.sqrt(a * a + b * b);
    }
    /*--------TIMER---------*/
    public static void getTime(String text) {
        if (BEFORE == 0) {
            BEFORE = System.currentTimeMillis();
            return;
        }
        long now = System.currentTimeMillis();
        long elapsed = (now - BEFORE);
        BEFORE = System.currentTimeMillis();
        if (text.equals("")) {
            return;
        }
        String message = "\r\n" + text + "\r\n" + "Elapsed time: " + elapsed + " ms";
        System.out.println(message);
    }

    public static void main(String[] args) {
        double a = 0.2223221101;
        double b = 122333.167;
        getTime("");
        /*--------DIRECT CALCULATION---------*/
        for (int i = 1; i < COUNT; i++) {
            Math.sqrt(a * a + b * b);
        }
        getTime("Direct: ");
        /*--------METHOD---------*/
        for (int k = 1; k < COUNT; k++) {
            hypotenuse(a, b);
        }
        getTime("Method: ");
    }
}
+4  A: 

Zero difference for me either way.

If anything this just goes to demonstrate the perils of benchmarking micro-optimization. Don't do it. It's a complete waste of time.

As for why you're seeing a difference: no idea. I'm using JDK 6u17 (32 bit) with healthy memory sizings on Win7 Ultimate 64. Perhaps you're using a different version. Perhaps this is an issue with JIT compilation.

Whatever the cause, worrying about the difference between having a method call and not having a method call is an irrelevant distraction.

cletus
+2  A: 
polygenelubricants
It is clear there are many aspects involved, but in this case I always experience the same beahviour, not random results.
plastilino
@plastilino: instead of discarding the result, try `sum += ...` instead, and then compare the two.
polygenelubricants
@polygenelubricants Not sure I undertand very well.I tried in both loops double h=...; int sum=0; sum+=h;Same results
plastilino
A: 

It is hard to be sure, but I suspect that the JIT compiler may be able to optimize the "direct" version, because it has figured out that the result of the computation is never used. It might be able to do this because it has built-in knowledge that Math.sqrt is side-effect free. By contrast, it would be harder to figure out that your hypotenuse method is side-effect free.

Anyway, as others have said, strange results like this are common when people try to write micro-benchmarks for Java.

Stephen C
I could be. But when I place the method loop in the first place I don't observe the big dealy.
plastilino
Perhaps it is JVM warmup / JIT compilation. Anyway, you should specify what JVM you are using so that people can reproduce what you are seeing.
Stephen C
A: 

If you really want to perform micro-bench marking then I suggest you use libraries like Japex (https://japex.dev.java.net/) to help you. Also read http://www.ibm.com/developerworks/java/library/j-jtp12214/

Pangea