简单Java程序的奇怪性能结果

时间:2011-04-21 18:11:38

标签: java performance

在Java中查看以下代码:

long l = System.currentTimeMillis();
int[] arr = new int[2];
for (int i = 0; i < arr.length; i++) {
  for (int j = 0; j < 600000000; j++) {
    arr[i] += 1;
  }
}
System.out.println("done " + (System.currentTimeMillis() - l));

我的(双核)机器需要大约3.5秒。

如果我添加行

int u = 0;

在开始时(在l l声明之前)需要6.5秒!

如果我现在添加额外的行,那么我有:

int u = 0;
int u2 = 0;

我们回到3.5秒。

使用

int u = 0;
int u2 = 0;
int u3 = 0; 
再过6.5秒!

和4是3.5秒,并且不断有5和更多3.6。

这是否发生在别人的机器上?这里发生了什么?

要查看JIT或JVM启动是否有任何影响,我将整个过程包装在一个100次迭代的循环中,结果仍然是相同的

5 个答案:

答案 0 :(得分:2)

我在所有情况下都得到2秒。由于其他原因,你可能会得到不同的结果。影响微观基准的因素有很多种。见How do I write a correct micro-benchmark in Java?

答案 1 :(得分:1)

乍一看,我会说不用担心 - 你基本上是在迷恋微基准测试的结果。几乎不可能是确定性的;即使存在实际的性能差异,也很可能是因为JIT试图找出额外变量正在做什么,以及是否存在副作用。

做一个完整的热身,你会得到更多确定性的结果,但它仍然是一个微基准。

答案 2 :(得分:0)

我不认为这是关于java的。

也许您正在运行其他进程,在执行时使用您的CPU。

你可能想把另一个for循环跨越所有其他代码并获得平均时间来尝试相同的事情50次。

当我尝试你的代码时,我的电脑上的所有情况总是需要3.4秒。

答案 3 :(得分:0)

我只有解释数据/缓存对齐。数据已经完全对齐以提供良好的性能,但添加其他变量可能会使事情有所改变,从而提供更高或更低的缓存命中率。

我个人认为,想知道为什么你的系统需要几秒钟才更有意思。我的代码大约在88毫秒! (四核2x2 2.66 GHz Mac Pro)

修改 找到原因,32位JVM需要2.5秒,64位88ms。

答案 4 :(得分:0)

您应该考虑JVM启动时间。