在下面的代码中,有没有办法避免使用if语句?
s = 13; /*Total size*/
b = 5; /*Block size*/
x = 0;
b1 = b;
while(x < s)
{
if(x + b > s)
b1 = s-x;
SendData(x, b1); /*SendData(offset,length);*/
x += b1;
}
非常感谢!
答案 0 :(得分:2)
我不知道也许你会想:
s = 13; /*Total size*/
b = 5; /*Block size*/
x = 0;
while(x + b < s)
{
SendData(x, b); /*SendData(offset,length);*/
x += b;
}
SendData(x, s%b);
更好吗?
答案 1 :(得分:1)
不要把时间浪费在你的编译器可能为你做的毫无意义的微优化上。
程序员的程序;不是电脑。编译器变得越来越好,但程序员却没有。
如果它使你的程序更具可读性(@PaulPRO的答案),那就去做吧。否则,不要。
答案 2 :(得分:0)
如果您尝试删除if()
,则可能会更改您的逻辑,您必须花费大量时间进行测试。我只看到一个潜在的变化:
s = 13;
b = 5;
x = 0;
b1 = b;
while(x < s)
{
const unsigned int total = x + b; // <--- introduce 'total'
if(total > s)
b1 = s-x;
SendData(x, b1);
x = total; // <--- reusing it
}
答案 3 :(得分:0)
您可以使用conditional move或branchless integer select分配b1而不使用if语句:
// if a >= 0, return x, else y
// assumes 32-bit processors
inline int isel( int a, int x, int y ) // inlining is important here
{
int mask = a >> 31; // arithmetic shift right, splat out the sign bit
// mask is 0xFFFFFFFF if (a < 0) and 0x00 otherwise.
return x + ((y - x) & mask);
};
// ...
while(x < s)
{
b1 = isel( x + b - s, s-x, b1 );
SendData(x, b1); /*SendData(offset,length);*/
x += b1;
}
但这只是对有序处理器的有用优化。它在现代PC的x86上没有任何区别,它具有快速分支和重新排序单元。它可能在某些嵌入式系统(如Playstation)上很有用,其中pipeline latency对于性能而言比指令计数更重要。我用它在紧密的循环中剃了几微秒。
理论上,编译器“应该”能够将三元表达式(b = (a > 0 ? x : y)
)转换为条件移动,但我从来没有遇到过这样做过。
当然,从更广泛的意义上说,与SendData()
的成本相比,每个人都认为这是无意义的优化是正确的。 cmov和分支之间的差异大约是4纳秒,与网络呼叫的成本相比可以忽略不计。花费你的时间修复这个分支,每次网络呼叫发生一次,就像开车穿越城镇,以节省汽油1美分。