如果m_NeedParentUpdate 不是false,则循环增加value count 倍。
从生成的代码来看,m_NeedParentUpdate 似乎是一个布尔值,存储为无符号字节,位于this 的偏移量0。优化器可能检测到m_NeedParentUpdate 是循环中的常量,因此可以将测试移到循环外。程序员应该已经用这种方式编写了代码,这可能是 Mike Acton 所指的我相信你可以在脑海中优化它。
这是一个重写的版本:
class Foo {
bool m_NeedParentUpdate;
int Bar(int count);
};
int Foo::Bar(int count) {
int value = 0;
if (m_NeedParentUpdate) {
for (int i = 0; i < count; i++) {
value++;
}
}
return value;
}
但是请注意,进一步优化代码在你的头脑中可能会导致循环减少到value += count;,但这对于count的负值是不正确的,这在第一眼。
优化器可以检测循环模式并优化为:
int Foo::Bar(int count) {
int value = 0;
if (m_NeedParentUpdate) {
if (count >= 0) {
value += count;
}
}
return value;
}
或等效:
int Foo::Bar(int count) {
int value = 0;
if (count >= 0) {
if (m_NeedParentUpdate) {
value = count;
}
}
return value;
}
将m_ParentNeedUpdate 转换为unsigned 并将其取反为false 生成0,为true 生成所有位。使用此值屏蔽count 将产生0 或count。
int Foo::Bar(int count) {
int value = 0;
if (count >= 0) {
value = -(unsigned)m_NeedParentUpdate & count;
}
return value;
}
但是请注意,代码仍然有一个测试和一个分支指令。可以进一步优化为:
int Foo::Bar(int count) {
// equivalent code, but definitely not readable
return -(unsigned)m_NeedParentUpdate & -(unsigned)(count >= 0) & count;
}
用gcc 和clang 编译它会产生无分支代码,如GodBolt's Compiler Explorer 所示。但是这两个编译器都没有将原始代码简化为这一行。