【发布时间】:2018-11-30 06:36:05
【问题描述】:
我试图更好地了解导致计算 branch prediction 的原因,以及不计算的原因。
例如,我有一个包含 1 和 0 的数组。我想遍历这个数组,如果它读到 0 做某事,但如果它读到 1 做别的事情。
使用 JavaScript 会如下所示:
var array = [0, 1, 1, 1, 0, 0, 0];
for(i=0; i < array.length; i++){
if(array[i] == 0){
// Do The 0 Instruction
}else{
// Do The 1 Instruction
}
}
我知道这将导致进行分支预测,因为程序在从数组中读取数据之前不知道需要采取哪些步骤。
但是,如果我对数组进行预处理以将连续 1 或 0 的数量组合成一个数字会怎样。因此,例如数组将更改为:
var array = [0, 1, 1, 1, 0, 0, 0];
var condensedArray = [1, 3, 3];
现在我可以使用这样的循环,而不是使用 if 语句来分支我的指令:
var condensedArray = [1, 3, 3];
for(i=0; i < condensedArray.length; i+=2){
for(j=0; j < condensedArray[i]; j++)
//Do The 0 Instruction
for(j=0; j < condensedArray[i+1]; j++)
//Do The 1 Instruction
}
这是否仍会导致分支预测被计算和错过?如果是这样,是否至少比使用 if 语句测试原始数组的每个索引更有效?
编辑: 在 cmets 中,有人问我如何知道数组是以 0 还是 1 开头的?为了简单起见,我把它省略了,不想再编辑上面的代码,但我会在程序的开头有一个 if 语句,说明数组是否以 0 或 1 开头。然后那个分支会以正确的顺序放置循环。
【问题讨论】:
-
在第一个 for 循环中你怎么会总是 0 情况让我们考虑这个数组 [1,0,0,1,1] 它会失败,第二个问题是当我变成 2 秒循环会抛出异常 ArrayindexOutOfException。
-
@DHARMENDRASINGH 为了简单起见,我把它排除在外,但基本上我会在程序开头有一个 if 语句,说明如果数组以 0 或 1 开头,那么该单个分支将将以下循环按顺序排列。抱歉,我将编辑我的答案以反映这一点。
-
我没有看到像这样优化的好处。添加更多分支不会提高性能。对数据进行排序肯定会有所帮助,这基本上就是您在第二个示例中尝试做的事情。但是,排序需要时间,所以除非您要重用数据,否则没有意义。
-
@ffhighwind 排序将在客户端运行程序之前完成。这是给客户哪个数组的问题。它如何添加更多分支?这就是我想要弄清楚的。
标签: javascript arrays performance branch-prediction