📜  为什么处理排序数组要比未排序数组快?

📅  最后修改于: 2021-04-27 05:09:56             🧑  作者: Mango

这是一个C++代码,它说明了对数据进行奇迹般的排序使代码比未排序的版本更快。让我们尝试一个示例C++程序,以更好地理解问题陈述。

// CPP program to demonstrate processing
// time of sorted and unsorted array
#include 
#include 
#include 
using namespace std;
  
const int N = 100001;
  
int main()
{
    int arr[N];
  
    // Assign random values to array
    for (int i=0; i

输出 :

Execution 1:
Time for unsorted array :: 0.00108
Time for sorted array :: 0.00053

Execution 2:
Time for unsorted array :: 0.001101
Time for sorted array :: 0.000593

Execution 3:
Time for unsorted array :: 0.0011
Time for sorted array :: 0.000418

请注意,与未排序的数组相比,处理排序的数组所花费的时间更少。排序数组优化的原因是分支预测。

什么是分支预测?
在计算机体系结构中,分支预测意味着确定程序指令流中的条件分支(跳转)是否可能被采用。
所有流水线处理器都以某种形式进行分支预测,因为它们必须在执行当前指令之前猜测要提取的下一条指令的地址。

分支预测如何适用于上述情况?

if条件检查arr [i] <5000 ,但是如果您观察到排序数组的情况,则在传递数字5000后条件始终为false,而在此条件之前始终为true,编译器会在此处优化代码并跳过if这种情况称为分支预测。

情况1:排序数组

T = if condition true
    F = if condition false
    arr[] = {0,1,2,3,4,5,6, .... , 4999,5000,5001, ... , 100000}
            {T,T,T,T,T,T,T, .... , T,    F,   F,   ... ,    F  }    

我们可以观察到,很容易预测排序数组中的分支,因为序列是TTTTTTTTTTTT………FFFFFFFFFFFFF

情况2:未排序的数组

T = if condition true
    F = if condition false
    arr[] = {5,0,5000,10000,17,13, ... , 3,21000,10}
            {T,T,F,     F,   T, T, ... , T, F,    T}

这是很难预测的,如果说明会或真或假,因此分支预测这里不扮演任何角色显著。

分支预测适用于算法遵循的模式或基本上是历史的模式,以及在先前步骤中是如何执行的。如果猜测正确,则CPU继续执行,如果出错,则CPU需要刷新管道并回滚至分支,然后从头开始重新启动。

如果编译器无法将分支预测用作提高性能的工具,则程序员可以实施自己的技巧来提高性能。

参考 :

  • Branch_prediction
  • 堆栈溢出
  • 计算流水线