if语句的效率

这个帖子的内容非常精彩。

http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array



大概内容是在这样的,有这么一条语句:

if (data[c] >= 128)
    sum += data[c];
data数组是排过序的(不管逆序还是顺序),那么执行效率非常高。

如果data数组是乱序的,那么执行效率极低。


造成这一现象的原因编译器是“分支预取”技术。

如果前一次 data[i]>128,那么下一次认为data[i+1]>128的可能性非常大,所以对于流水线技术的cpu来说,会预取分支内的代码。

所以说,对于排过序的数组来说,或许只有 “ data[6]<128 data[7]=128 data[8]>128”,当 i = 8时,cpu丢掉了预取得东西。

对于乱序的数组来说,那cpu丢弃预取的数据的概率是50%。

效率当然不同。


这段话对应的原文内容如下:

T = branch taken N = branch not taken data[] = 0, 1, 2, 3, 4, ... 126, 127, 128, 129, 130, ... 250, 251, 252, ... branch = N N N N N ... N N T T T ... T T T ... = NNNNNNNNNNNN ... NNNNNNNTTTTTTTTT ... TTTTTTTTTT (easy to predict)
data[] = 226, 185, 125, 158, 198, 144, 217, 79, 202, 118, 14, 150, 177, 182, 133, ... branch = T, T, N, T, T, T, T, N, T, N, N, T, T, T, N ... = TTNTTTTNTNNTTTN ... (completely random - hard to predict)

解决方法:


if (data[c] >= 128) sum += data[c];

变成:

int t = (data[c] - 128) >> 31; sum += ~t & data[c];

当然,前提是降低了可读性。


你可能感兴趣的:(if语句的效率)