【发布时间】:2014-06-30 03:48:48
【问题描述】:
我刚刚在一些 Java 玩具示例中观察到一个奇怪的性能问题。这是完整的程序:
import java.util.Random;
public class Weird
{
public static long fib(int n)
{
long a = 0;
long b = 1;
for (long i = 0; i < n; ++i) // note: loop counter of type long
{
long c = a + b;
a = b;
b = c;
}
return a;
}
public static void main(String[] args)
{
System.out.print("Warming up the JIT... ");
warmUpTheJIT();
System.out.println("Starting measurement");
long bogus = 0L;
long before = System.nanoTime();
for (int i = 0; i < 500_000_000; ++i)
{
bogus += fib(46);
}
long after = System.nanoTime();
System.out.println(bogus);
long duration = after - before;
long ms = duration / 1_000_000;
System.out.println(ms +" ms");
}
private static void warmUpTheJIT()
{
Random rand = new Random();
long bogus = 0L;
for (int i = 0; i < 1_000_000; ++i)
{
bogus += fib(rand.nextInt(47));
}
System.out.println(bogus);
}
}
代码在我的系统(64 位 Java 8 VM)上需要 21 秒。但是,如果我将循环计数器从 long 更改为 int,则只需 27 毫秒。这大约快了三个数量级。
那么...为什么循环计数器的类型会产生如此巨大的差异?
【问题讨论】:
-
如果你把它改成
short它会运行什么 -
我们不是在讨论
fib函数中的for循环吗?永远不会看到大于 47 的值,这肯定适合short。然而,这将是糟糕的代码,因为参数类型是int并且 可能 比 short 大。 -
JIT 对
int计数器使用了许多优化。通常不会有太大的不同,但它们可以产生很大的不同,这种情况很少见。
标签: java performance loops for-loop long-integer