是否值得使用位向量/数组而不是简单的bool数组?

时间:2008-10-07 01:35:23

标签: performance optimization

当我需要一个标志数组时,它通常会让我使用整个字节(或单词)来存储每个标志,如果我创建一个bool或其他数字的数组,结果就是这样。可以设置为0或1的类型。但现在我想知道使用更节省空间的结构是否值得(尽管希望非常轻微)移位和位测试的额外开销。

在我的公司,我们使用Rogue Wave工具(虽然希望时间不长),而且到目前为止,我已经将RWBitVec用于此目的。

6 个答案:

答案 0 :(得分:5)

主要是关于节省记忆。如果您的bool数组足够大,存储空间的8倍改进是有意义的,那么无论如何都要使用bitarray。

请注意,与shift /相比,内存访问相当昂贵,因此bitarray方法比chars数组略快。基本上它归结为内存与程序员时间。请记住,过早优化是浪费时间。我会使用最容易开发的方法,然后只有在它显示出它是主要的性能瓶颈之后才进行重构。

答案 1 :(得分:3)

不要使用vector< bool>,它实际上不是Container:

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=98

在适当的地方使用std :: bitset(用于固定大小的位集)和boost :: dynamic_bitset(用于可调整大小的位集)。它们也不是容器,但它们看起来不应该如此,因此不太可能引起混淆。

权衡是否值得,显然取决于程序中阵列的大小。我认为你是正确的,因为位访问的开销通常可以忽略不计,但是如果内存开销也可以忽略不计,那么你也没什么可去的。

比特集的优势在于它们完全按照他们在锡上所说的那样做 - 没有一个“声明一组字符/整数,但唯一的合法值是0和1”无意义。您的代码将与您使用数组的内容相同。

答案 2 :(得分:2)

我编写了一些代码,将位图图像行解压缩为每个像素的单独字节,然后在处理后再将其打包。对于我进行基准测试的代码,实际上这样做比在位级工作更快。

答案 3 :(得分:2)

现代计算机具有barrel shifters,因此任意数量的位移到31都需要几个周期(少于许多其他指令)。编译器利用了这一点,位操作不仅节省空间,而且在大多数情况下节省时间。

但这实际上取决于你如何使用和测试这些位 - 有一些低效的方法会使整个整数更快。

- 亚当

答案 4 :(得分:2)

我使用了一个位数组来索引一个巨大的树。算法是:

    Check bitarray if entry exists
    if entry doesn't exists 
      return null
    else do binary search in tree
      return value

优点是Tree足够大,搜索不存在的条目会在完成之前导致多次缓存未命中。因此,算法需要更长时间或更长时间,具体取决于值的存在。

然而,添加初始位数组搜索意味着我会减少缓存未命中,并且如果答案不存在则会避免搜索树。通过添加这个额外的步骤,算法变得更加健壮(计算机上的实际执行时间变得接近线性,尽管Big-O会说不同),并且整体性能提高了一个数量级。

就像他们说有时考虑硬件比“理想”数学算法更重要。

答案 5 :(得分:0)

值得吗?只有当您知道存在内存使用问题时才能使用。

但除非你是:

  1. 使用非常有限的资源或
  2. 处理嵌入式处理器
  3. 存储天文数bool s
  4. 然后答案是否定的。使用位图比使用bool更难以在源中实现相同级别的可读性,除非您在前两个条件中运行,否则您可能会发现它没有对你的记忆足迹产生明显的影响。