回忆课上教的, 和几篇博文
https://blog.youkuaiyun.com/rrrfff/article/details/44993467?ticket=ST-106021-6fOewnguwhi3rUrgYAUb-passport.youkuaiyun.com
都提到了分支预测正确时可以给程序带来一定的性能提升, 为此利用JMH写了个简单的测试例子, 但并没有得到想要的结论:
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 2)
@Measurement(iterations = 5)
@State(Scope.Benchmark)
@Fork(1)
public class BranchPredicateTest {
private final int n = 100_0000;
private List<Integer> list1;
private List<Integer> list2;
private List<Integer> list3;
private int mid;
@Setup
public void setup() {
Random random = new Random();
list1 = new ArrayList<>(n);
for (int i = 0; i < n; ++i) {
int x = random.nextInt();
list1.add(x);
}
// Collections.shuffle(list1);
list2 = new ArrayList<>(list1);
list2.sort(Integer::compare);
mid = list2.get(n - 1);
list3 = new ArrayList<>(list1);
list3.sort((a, b) -> Integer.compare(b, a));
}
@Benchmark
public void test_1(Blackhole b) {
int mid = this.mid;
List<Integer> list = this.list1;
int count = 0;
for (int i = 0; i < n; ++i) {
Integer x = list.get(i);
if (x < mid) {
++count;
}
}
b.consume(count);
}
@Benchmark
public void test_2(Blackhole b) {
int mid = this.mid;
List<Integer> list = this.list2;
int count = 0;
for (int i = 0; i < n; ++i) {
Integer x = list.get(i);
if (x < mid) {
++count;
}
}
b.consume(count);
}
@Benchmark
public void test_3(Blackhole b) {
int mid = this.mid;
List<Integer> list = this.list3;
int count = 0;
for (int i = 0; i < n; ++i) {
Integer x = list.get(i);
if (x < mid) {
++count;
}
}
b.consume(count);
}
}
结果是
Benchmark Mode Cnt Score Error Units
BranchPredicateTest.test_1 thrpt 5 768.592 ± 160.822 ops/s
BranchPredicateTest.test_2 thrpt 5 110.549 ± 7.976 ops/s
BranchPredicateTest.test_3 thrpt 5 111.322 ± 16.005 ops/s
恢复被注释掉的那行之后却得到了不同的结论:
Benchmark Mode Cnt Score Error Units
BranchPredicateTest.test_1 thrpt 5 111.782 ± 11.104 ops/s
BranchPredicateTest.test_2 thrpt 5 115.126 ± 10.607 ops/s
BranchPredicateTest.test_3 thrpt 5 113.624 ± 20.216 ops/s