我有一个这样的循环:
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编译,也可以理解。
由于
答案 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
是一个指向局部变量的指针,那么编译器会在循环的持续时间内将值拉入寄存器 - 所以它认为值得做!