我正在编写一些环形缓冲器,这个问题问了我好几次。
苏普豪斯,我们有一个计数器,我们需要在一定数量后重新设置。我已经看到了几个环形缓冲区的例子(主要是音频,围绕r/w指针进行包装),它们可以做到这一点:
x++;
if (x == SOME_NUMBER ){ // Reseting counter
x -= x;
}在这样做时是否有任何区别/偏好:
x++;
if (x == SOME_NUMBER ){ // Reseting counter
x = 0;
}这个问题适用于几乎所有类型的变量重置。在我的情况下,除了响蜂鸣器,我也重新设置一个计数器,做一个平均,所以我做了我的所有措施,我重新设置了计数器。
除了结果可能是相同的(x重新计算为零)之外,一种方法和另一种方法可能有一些不同。有什么偏好吗?
发布于 2019-07-11 14:38:11
考虑一下那些稍微修改过的片段版本。
void f(int n)
{
int x = 0;
for (;;)
{
++x;
if (x == n ) { // Reseting counter
x -= x;
}
// Ending condition to avoid UB
if ( x == 42 )
return;
}
}
void g(int n)
{
int x = 0;
for (;;)
{
++x;
if (x == n ) {
x = 0;
}
if ( x == 42 )
return;
}
}如果您查看生成的程序集(例如使用编译器资源管理器),您将注意到现代优化编译器如何利用以此类推。
Clang (使用-O2)为这两个函数生成相同的机器代码。它用
xor eax, eax将零加载到寄存器中,然后
cmove ecx, eax在需要时“重置”另一个寄存器。
Gcc只是创建了f(),然后g()变成了
jmp f(int)那就说
有什么偏好吗?
一个常见的指导方针是编写更易读和更易于维护的代码,并在对其进行分析之后才探索可能的优化。
在大多数情况下,我会使用x = 0;版本,因为它更好地传达了意图,IMHO。我只能想到采用x -= x;的几个理由:
42文本就是这样的,0是一个例外情况。x不是int的任何情况。发布于 2019-07-11 13:20:09
不同之处在于操作的数量:x -= x是减法和赋值,而x = 0只是赋值。除了CPU周期的数量之外,如果可以从其他线程访问x,则会影响行为。
一个简单的任务x = 0也要清楚得多。
https://stackoverflow.com/questions/56989823
复制相似问题