编辑:在 C++ 中,如果我有,我需要测试 8 个标志。就处理速度而言,这将更有效:
在单个 if 语句中检查 8 个 bool 变量或使用 char 表示标志,每个标志有 1 位,并在单个 if 语句中使用单个按位运算?
如果我有 1 个标志要测试,那会有什么不同吗?
编辑:在 C++ 中,如果我有,我需要测试 8 个标志。就处理速度而言,这将更有效:
在单个 if 语句中检查 8 个 bool 变量或使用 char 表示标志,每个标志有 1 位,并在单个 if 语句中使用单个按位运算?
如果我有 1 个标志要测试,那会有什么不同吗?
如果您想要检查的所有位都有一个已知值,那么比较 a 可能会更快:char
if (bitval == 0x82) ...
如果您想检查某些位,而忽略其他位,将“位”保存在单独的变量中可能会更快:
if ((bitval7 == 1) && (bitval1 == 1)) ...
或者,简单地屏蔽掉您不关心的位可能会更快:
if ((bitval & 0x82) == 0x82) ...
如果您真的很担心,您可以选择以两种方式存储它们(前提是您保持它们同步)并根据您感兴趣的位数进行选择。
但我认为这是严重的过度杀伤,因为老实说,速度差异可能非常小,以至于无关紧要。
如果你要进行优化,你几乎总能在算法选择等宏观方面获得更好的投资回报,而不是像分离布尔值或改变循环方向这样的微观优化。
不要误会我的意思,这些微优化可以在某些情况下产生影响,但它们通常不是最好的方法。
我通常是按位标志的粉丝,但我发现拥有一些支持功能通常会有所帮助:
inline bool TestAll( char flags, char value ) {
return (flags & value) == value;
}
inline bool TestAny( char flags, char value ) {
return (flags & value) != 0;
}
inline bool TestAllExclusive( char flags, char value ) {
return flags == value;
}
inline bool TestAnyExclusive( char flags, char value ) {
return (flags & value) != 0 && (flags & ~value) == 0;
}
您还可以执行类似的功能来获取标志掩码,使所有这些神奇的东西更容易阅读。
如果您有要测试的真值,那么这在速度方面是赢家,因为您只是在使用常量。
typedef enum EmotiveFlags {
E_ELATED = 0x01,
E_JOYOUS = 0x02,
E_NONPLUSED = 0x04,
E_BEWILDERED = 0x08,
E_ANNOYED = 0x10,
E_PUZZLED = 0x20,
E_ENRAGED = 0x40,
E_AMUSED = 0x80
} EEmotiveFlags;
if( TestAny(flags, E_JOYOUS | E_ELATED | E_AMUSED) ) {
//...
}
else if( TestAll(flags, E_ANNOYED | E_ENRAGED) && !TestAll(flags, E_AMUSED) ) {
//...
}
这个问题真的归结为编译器。这取决于它如何引用要检查的位,但是,我相信可以肯定地说,只要您检查多个位,char 会更快。
运行 char 所需的时钟周期量将明显短于单个变量,因为标志在内存中相邻堆叠,从而消除了内存寻址的要求。
但是,如果您想要明显的速度差异,除非您更改检查方法,否则您将无法获得它。
好吧,最好的选择是将代码编译到汇编器并检查它。
8 个布尔标志需要 8 个寄存器。这是很多。8 位标志只需要一个寄存器。如果您将所有标志放在一个寄存器中,则测试速度会非常快。