0

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: ");
    }
}
  • No difference for me. I'm using Java 1.6. – Apprentice Queue May 16 '10 at 05:39
  • This is an extremely simplistic JIT inline to get the same performance. This is going to be controlled purely by JVM choice and settings. If it doesn't do the inline, you'll get the numbers you got. What is your JVM and settings? – Michael May 16 '10 at 05:52
  • Micheal, I'm using the Sun one, default settings, inside IntelliJ Idea. No adittional parameters in the command line. – plastilino May 16 '10 at 09:37
  • I tried with Jikes and the same big difference. My PC has Windows x64. I have a latop with 32 bits XP, no differneces in it. The issue affects only to the 64 bits OS. – plastilino May 16 '10 at 10:33

4 Answers4

4

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
  • 616,129
  • 168
  • 910
  • 942
2

I get comparable numbers as expected.

In any case, this kind of microbenchmarking won't reveal any performance problems. You need to use a real profiler, and you need to let HotSpot warm-up, etc. Just timing one loop then another won't reliably compare the performance of two constructs.

Related questions

Related links

  • JavaOne 2002 presentation S-1816 How NOT To Write A Microbenchmark
  • Benchmarking the Java HotSpot VM

    What do you recommend for benchmarking HotSpot, or any virtual machine?

    The best answer here is to use real applications for benchmarking, as they are the only thing that makes a real difference. If that's not possible, use standard SPEC benchmarks followed by other well respected industry benchmarks. Microbenchmarks should be avoided, or at least used with much caution. It's very common for microbenchmarks to give misleading answers due to optimization effects.

Community
  • 1
  • 1
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
0

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
  • 698,415
  • 94
  • 811
  • 1,216
  • I could be. But when I place the method loop in the first place I don't observe the big dealy. – plastilino May 16 '10 at 09:31
  • 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 May 16 '10 at 09:34
0

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/

Aravind Yarram
  • 78,777
  • 46
  • 231
  • 327