我对此感到困惑。
在我的机器中
你在机器上检查了吗?
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: ");
}
}
答案 0 :(得分:4)
如果有什么事情可以证明基准微优化的风险。不要这样做。这完全是浪费时间。
至于为什么你会看到差异:不知道。我在Win7 Ultimate 64上使用JDK 6u17(32位)和健康的内存大小。也许你正在使用不同的版本。也许这是JIT编译的一个问题。
无论原因是什么,担心方法调用和没有方法调用之间的区别是一种无关紧要的分心。
答案 1 :(得分:2)
我得到了与预期相当的数字。
无论如何,这种微基准测试不会发现任何性能问题。你需要使用一个真正的探查器,你需要让HotSpot预热等等。只需计时一个循环,然后另一个循环不能可靠地比较两个结构的性能。
您对HotSpot或任何虚拟机进行基准测试的建议是什么?
这里最好的答案是使用真正的应用程序进行基准测试,因为它们是唯一能够产生真正差异的东西。如果无法做到这一点,请使用标准SPEC基准测试,然后使用其他备受推崇的行业基准测试。 应避免使用微量标记,或至少谨慎使用。微基准测试由于优化效果而给出误导性答案是很常见的。
答案 2 :(得分:0)
很难确定,但我怀疑JIT编译器可能能够优化“直接”版本,因为它已经发现从未使用过计算结果。它可能能够做到这一点,因为它具有Math.sqrt无副作用的内置知识。相比之下,更难以确定您的hypotenuse
方法是无副作用的。
无论如何,正如其他人所说,当人们试图为Java编写微基准时,这种奇怪的结果很常见。
答案 3 :(得分:0)
如果你真的想进行微工作台标记,那么我建议你使用像Japex(https://japex.dev.java.net/)这样的库来帮助你。另请阅读http://www.ibm.com/developerworks/java/library/j-jtp12214/