【发布时间】:2015-08-07 21:53:38
【问题描述】:
在这段代码中,当我在 main 方法中创建一个对象然后调用该对象方法:ff.twentyDivCount(i)(runs in 16010 ms) 时,它的运行速度比使用此注释调用它快得多:twentyDivCount(i)(runs 59516 毫秒)。当然,当我在不创建对象的情况下运行它时,我将方法设为静态,因此可以在 main 中调用它。
public class ProblemFive {
// Counts the number of numbers that the entry is evenly divisible by, as max is 20
int twentyDivCount(int a) { // Change to static int.... when using it directly
int count = 0;
for (int i = 1; i<21; i++) {
if (a % i == 0) {
count++;
}
}
return count;
}
public static void main(String[] args) {
long startT = System.currentTimeMillis();;
int start = 500000000;
int result = start;
ProblemFive ff = new ProblemFive();
for (int i = start; i > 0; i--) {
int temp = ff.twentyDivCount(i); // Faster way
// twentyDivCount(i) - slower
if (temp == 20) {
result = i;
System.out.println(result);
}
}
System.out.println(result);
long end = System.currentTimeMillis();;
System.out.println((end - startT) + " ms");
}
}
编辑:到目前为止,似乎不同的机器会产生不同的结果,但使用 JRE 1.8.* 似乎可以始终如一地重现原始结果。
【问题讨论】:
-
你是如何运行你的基准测试的?我敢打赌,这是 JVM 没有足够时间优化代码的产物。
-
看来 JVM 已经有足够的时间来编译并为 main 方法执行 OSR,如
+PrintCompilation +PrintInlining所示 -
我已经尝试过代码 sn-p ,但我没有像 Stabbz 所说的那样得到任何时差。他们56282ms(使用实例)54551ms(作为静态方法)。
-
@PatrickCollins 五秒钟就足够了。我rewrote it a bit 以便您可以测量两者(每个变体启动一个 JVM)。我知道作为基准它仍然存在缺陷,但它足以令人信服:1457 ms STATIC vs 5312 ms NON_STATIC。
-
还没有详细调查这个问题,但是这个可能是相关的:shipilev.net/blog/2015/black-magic-method-dispatch(也许 Aleksey Shipilëv 可以在这里启发我们)
标签: java performance object methods static