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: ");
}
}
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.
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
- What is microbenchmarking?
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.
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.
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/
精彩评论