我有一个C ++应用程序,其中包含许多具有手动控制位字段的结构,类似于
#define FLAG1 0x0001
#define FLAG2 0x0002
#define FLAG3 0x0004
class MyClass
{
'
'
unsigned Flags;
int IsFlag1Set() { return Flags & FLAG1; }
void SetFlag1Set() { Flags |= FLAG1; }
void ResetFlag1() { Flags &= 0xffffffff ^ FLAG1; }
'
'
};
出于显而易见的原因,我想将其更改为使用位字段,例如
class MyClass
{
'
'
struct Flags
{
unsigned Flag1:1;
unsigned Flag2:1;
unsigned Flag3:1;
};
'
'
};
我在进行此切换时遇到的一个问题是,我在此站点上遇到过许多引用,说明C ++中的位字段有多慢。我的假设是它们仍然比上面显示的手动代码更快,但是有没有任何硬参考资料涵盖在各种平台上使用位字段的速度影响,特别是32位和64位窗口。该应用程序处理内存中的大量数据,并且必须具有快速和内存效率,这很可能是它首先以这种方式编写的原因。
答案 0 :(得分:5)
这两个例子的速度应该非常相似,因为在两种情况下编译器都必须最终发出相同的位掩码指令。要知道哪个是最好的,运行一些简单的实验。但如果结果不确定,不要感到惊讶;这就是我所预测的......
你可能会更好地说这些位域的类型为bool
。
答案 1 :(得分:5)
除非这是一个非常非常非常紧凑的循环,否则两者在性能上没有任何选择,如果性能真的很重要使用bool(即可能是32位值)。
使用仅包含三个单个位字段的结构仍将填充至至少 32位。如果您完全专注于保存每一个可能的位置,请查看编译器关于对齐和填充结构的文档。
编辑: 支持位域的一个原因是它们可以制作更整洁的代码,并且不应低估可维护性的重要性。与程序员时间相比,计算机时间便宜!
答案 2 :(得分:1)
针对此类问题的一般建议:设置一个简单的程序,尽可能准确地比较您的情况(操作,硬件等)并自行衡量您的表现差异。
对于关于位域与屏蔽的这个问题,我怀疑你会发现显着的性能差异 - 根据编译器的不同,位域代码可能需要一个或两个以上的屏蔽。在您的应用程序中是否明显是您需要回答的问题。例如,掩模可编程嵌入式代码与桌面应用程序的考虑因素存在很大差异。