Modulo vs循环中的if语句

时间:2014-08-12 11:24:31

标签: c++ c

我有一个这样的循环:

for(i = 0; i < arrayLength; i++)
{
    result[i / 8] = SETBIT(result[i / 8], ++(*bitIndex), array[i]);
    *bitIndex %= 8;
}

我想知道如果我使用上述风格或者这种风格,表现更好,性能更好:

for(i = 0; i < arrayLength; i++)
{
    result[i / 8] = SETBIT(result[i / 8], ++(*bitIndex), array[i]);
    if(*bitIndex == 8) *bitIndex = 0;
}

这是在C中,用GCC编译,也可以理解。

由于

3 个答案:

答案 0 :(得分:5)

谈论优化没有任何意义......

  • 没有特定的目标系统
  • 在确保所有编译器优化都已启用并正常工作之前
  • 在您执行某种基准测试之前

在您的情况下,对于大多数系统,两个示例之间没有区别。你真正应该关注的是编写可读代码,而不是反过来。考虑将您的程序重写为以下内容:

for(i = 0; i < arrayLength; i++)
{
    (*bitIndex)++;
    SETBIT(&result[i / 8], *bitIndex, array[i]);
    *bitIndex %= 8;
}

这可能会产生与你已经拥有的完全相同的二进制可执行文件,+ - 几个CPU滴答。

答案 1 :(得分:0)

老实说,它们之间只有一点点的差异。但我相信第一种对于简单的阅读风格来说会更好。但是,这个问题引用了性能,在这种性能中,我仍然认为第一个对于编译器正在读取/计算较少信息的事实具有EVER SO SLIGHT优势。

答案 2 :(得分:0)

你不能说为什么bitIndex是一个指针。但是,假设bitIndex是包含给定循环的函数的参数,我会将*bitIndex东西拉出循环,所以:

  unsigned bi = *bitIndex ;

  for(i = 0 ; i < arrayLength ; i++)
    {
      result[i / 8] = SETBIT(&result[i / 8], ++bi, array[i]) ;
      bi %= 8 ;
    } ;

   *bitIndex = bi ;

[我认为++bi是正确的,SETBIT()需要1..8,其中bi为0..7。]

如其他地方所述,编译器在早餐时使用% 8并将其替换为& 0x7(对于未签名但未签名)。使用gcc -O2,上面产生了一个48字节代码的循环(15条指令)。在循环中摆弄*bitIndex的是50个字节的代码(16个指令),包括*bitIndex的读取和两次写入。

这有多大的实际差异是任何人的猜测...可能是内存读取和写入完全由循环的其余部分包含。

如果bitIndex是一个指向局部变量的指针,那么编译器会在循环的持续时间内将值拉入寄存器 - 所以它认为值得做!