2

编辑:在 C++ 中,如果我有,我需要测试 8 个标志。就处理速度而言,这将更有效:

在单个 if 语句中检查 8 个 bool 变量或使用 char 表示标志,每个标志有 1 位,并在单个 if 语句中使用单个按位运算?

如果我有 1 个标志要测试,那会有什么不同吗?

4

4 回答 4

5

如果您想要检查的所有位都有一个已知值,那么比较 a 可能会更快:char

if (bitval == 0x82) ...

如果您想检查某些位,而忽略其他位,将“位”保存在单独的变量中可能会更快:

if ((bitval7 == 1) && (bitval1 == 1)) ...

或者,简单地屏蔽掉您不关心的位可能会更快:

if ((bitval & 0x82) == 0x82) ...

如果您真的很担心,您可以选择以两种方式存储它们(前提是您保持它们同步)并根据您感兴趣的位数进行选择。

但我认为这是严重的过度杀伤,因为老实说,速度差异可能非常小,以至于无关紧要。

如果你要进行优化,你几乎总能在算法选择等宏观方面获得更好的投资回报,而不是像分离布尔值或改变循环方向这样的微观优化。

不要误会我的意思,这些微优化可以在某些情况下产生影响,但它们通常不是最好的方法。

于 2012-09-07T02:53:18.940 回答
2

我通常是按位标志的粉丝,但我发现拥有一些支持功能通常会有所帮助:

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) ) {
   //...
}
于 2012-09-07T03:14:57.830 回答
1

这个问题真的归结为编译器。这取决于它如何引用要检查的位,但是,我相信可以肯定地说,只要您检查多个位,char 会更快。

运行 char 所需的时钟周期量将明显短于单个变量,因为标志在内存中相邻堆叠,从而消除了内存寻址的要求。

但是,如果您想要明显的速度差异,除非您更改检查方法,否则您将无法获得它。

于 2012-09-07T03:00:17.497 回答
0

好吧,最好的选择是将代码编译到汇编器并检查它。

8 个布尔标志需要 8 个寄存器。这是很多。8 位标志只需要一个寄存器。如果您将所有标志放在一个寄存器中,则测试速度会非常快。

于 2015-04-19T16:08:09.283 回答