【发布时间】:2014-02-21 08:00:48
【问题描述】:
关于this 问题,答案指定未排序数组需要更多时间,因为它未通过分支预测测试。但是如果我们对程序做一个小的改动:
import java.util.Arrays;
import java.util.Random;
public class Main{
public static void main(String[] args) {
// Generate data
int arraySize = 32768;
int data[] = new int[arraySize];
Random rnd = new Random(0);
for (int c = 0; c < arraySize; ++c) {
data[c] = rnd.nextInt() % 256;
}
// !!! With this, the next loop runs faster
Arrays.sort(data);
// Test
long start = System.nanoTime();
long sum = 0;
for (int i = 0; i < 100000; ++i) {
// Primary loop
for (int c = 0; c < arraySize; ++c) {
if (data[c] >= 128) {
sum = data[c];
}
}
}
System.out.println((System.nanoTime() - start) / 1000000000.0);
System.out.println("sum = " + sum);
}
}
这里我已经替换(来自原始问题)
if (data[c] >= 128)
sum += data[c];
与
if (data[c] >= 128)
sum = data[c];
未排序的数组给出了大约。同样的结果,我想问为什么分支预测在这种情况下不起作用?
【问题讨论】:
-
您在比较哪些结果?
-
我也使用了排序和未排序的数组。在 Core i5-3230M 上大约需要 5 秒,通常未排序的速度更快,但由于随机性,可以忽略...
-
拜托...这不是您在 JVM 上测量 anything 的方式。 Java 不是 C,它有一个非常复杂的 runtime,它会在某个时间点对代码进行 JIT 编译,这不是初始点——还有无数其他影响测量的问题。跨度>
-
@zapl "Java 不能在执行分支预测的处理器上运行" => 当然可以(或者学究一下:执行 java 代码的 JVM 可以)!
-
@MarkoTopolnik 我可以重现他的描述:使用
sum += data[c]有或没有排序显示性能差异(排序快3 倍)但使用sum = data[c]有或没有排序显示没有性能差异。跨度>
标签: java performance microbenchmark branch-prediction jmh