第四周_R-处理排序数组比未排序的要快

88 阅读2分钟

先给出结论:分支预测
作者使用以前火车人力预判改变匝道的案例,说明了预测对了,会话很少的时间。处理器都会有这种预测算法

有 if 语句的时候会遇到这种情况。评论区还有大神写出了替代 if 语句的代码,但是可读性极差

public class ProcessSortedArrayWithNoSorted {
    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.currentTimeMillis();
        long sum = 0;
        for (int i = 0; i < 100000; ++i)
        {    //循环十万次处理
            for (int c = 0; c < arraySize; ++c)
            {   // Primary loop
                if (data[c] >= 128) {
                    sum += data[c];
                }
                  //可以替换上面的整个 if 语句判断并且排序不排序都没有影响 ;但可读性可谓极差,但是帅
//                int t = (data[c] - 128) >> 31;
//                sum += ~t & data[c];
            }
        }

        System.out.println((System.currentTimeMillis() - start) / 1000.0);
        System.out.println("sum = " + sum);
    }
}

我自己本机运行结果:总的来说是排序快很多

未排序:7s 左右

排序:2s+

What is Branch Prediction

假设一个火车枢纽问题:

现在为了讨论问题,假设没有长距离或无线电通信。

你是一个火车枢纽的操作员并且你听到火车来了,但是你不能确定火车会往那边走。你只能让火车停下来,问司机,要往哪里走,然后你再操作路线。

火车很重,有很大的惯性,所以启动和停止都会费时费力。

有好的方法吗?你猜测火车的方向,然后提前转向:

  • 猜对,正常行驶
  • 错误。火车停下,重新启动

如果你总是猜对,那么火车不会停下

如果你经常猜错,那么火车会停下,在启动

现代程序都有良好的分支预测行为,准确率能高达90%,但是对于杂乱无章的数据,预测程序毫无作用。对于上面的 if 语句,就是一个分支。如果数据杂乱,那么每次预测对的情况是50%。但是排序了,在中间点上预测50%,其他前后都是 100% 预测对(相当于火车可以一直走)。