从逻辑(非技术)角度来看,没有优势。
任何普通的C / C ++代码都可以包装在适当的“库构造”中。在这样的包装之后,“这是否比它更具优势”的问题成为一个有争议的问题。
从速度的角度来看,C / C ++应该允许库构造生成与其包装的普通代码一样有效的代码。但是,这要遵守:
- 功能内联
- 编译时检查并消除不必要的运行时检查
- 消除死代码
- 许多其他代码优化...
使用这种非技术性的论据,任何人都可以添加任何“缺失功能”,因此不算作不利条件。
但是,内置的要求和限制无法通过其他代码来克服。下面,我认为的大小std::bitset
是一个编译时常量,因此尽管不算不利,但它仍然会影响用户的选择。
从美学的角度(可读性,易于维护等)来看,存在差异。
但是,尚不明显std::bitset
代码立即胜过普通C代码。人们必须查看更大的代码段(而不是一些玩具样本)来说明是否使用std::bitset
可以提高源代码的人工质量。
位操作的速度取决于编码样式。编码样式会影响C / C ++的位操作,并且同样适用于编码样式std::bitset
,如下所述。
如果编写的代码一次使用operator []
来读取和写入一位,那么如果要操纵的位超过一个,则必须多次执行此操作。C风格的代码也是如此。
但是,bitset
也有其他的运营商,诸如operator &=
,operator <<=
等,这对位集的整个宽度进行操作。因为底层机器通常可以一次(在相同的CPU周期数内)一次在32位,64位,有时甚至在128位(使用SIMD)上运行,所以设计用于利用这种多位操作的代码可以比“循环”位处理代码更快。
一般概念称为SWAR(寄存器内的SIMD),是位操作下的子主题。
一些C ++供应商可能bitset
使用SIMD 实现64位和128位之间的转换。一些供应商可能不会(但最终可能会)。如果需要知道C ++供应商的库在做什么,那么唯一的方法就是查看反汇编。
至于是否std::bitset
有局限性,我可以举两个例子。
- 的大小
std::bitset
必须在编译时知道。要制作具有动态选择大小的位数组,必须使用std::vector<bool>
。
- 当前的C ++规范
std::bitset
没有提供从bitset
M位中的较大位提取N位连续切片的方法。
第一个是基本的,这意味着对于需要动态大小的位集的人,他们必须选择其他选项。
可以克服第二个问题,因为即使标准不可扩展,也可以编写某种适配器来执行任务bitset
。
某些现成的高级SWAR操作未从中直接提供std::bitset
。可以在本网站上阅读有关位排列的这些操作。像往常一样,可以在之上运行自己实现这些功能std::bitset
。
关于性能的讨论。
一个告诫:很多人问为什么(东西)从标准库比一些简单的C风格的代码要慢得多。在这里,我不会重复进行微基准测试的先决知识,但是我只有以下建议:确保在“发布模式”(启用优化)中进行基准测试,并确保未消除代码(消除死代码)或吊离循环(循环不变代码运动)。
由于一般而言,我们无法分辨(互联网上)某人是否在正确地进行微基准测试,因此,我们可以得出可靠结论的唯一方法是自己做微基准测试,记录详细信息,并提交给公众审查和批评。重做其他人以前做过的微基准测试并没有什么坏处。
std::bitset
在编译时固定。这是我能想到的唯一严重的缺点。