如何在数组<bool> </bool>上使用bitoperations

时间:2014-04-18 01:47:22

标签: c++ arrays c++11

对于一些性能敏感项目(执行时间至关重要,内存不是问题)我需要某种容器,它可以容纳中等大小(最多500)个bool值。 大小在编译时是已知的,因此似乎有两个明显的选择:

bitset<500>array<bool,500>

在这些容器上,程序必须执行大量的操作并读取/设置单个值。

到目前为止,我使用了bitset,但是[] -operator对read / set元素的性能非常糟糕。由于数组明显优于bitset,我只需要在这些数组上使用逻辑运算符。

所以我想要的是以下内容:

array<bool,500> a,b,c;
c = b ^ a;   // ??? how to do it, need & and ^ 

我认为应该有一些与memcpy或类似的魔法......但直到现在我无法理解它。迭代整个数组不是一个选择。 (尝试过,它太慢了)

4 个答案:

答案 0 :(得分:1)

如果您不介意进行内存分配,可以使用std::valarray进行内存分配element-wise binary operators

#include <valarray>

int main()
{
    std::valarray<bool> a(500),b(500),c(500);
    c = b ^ a;
}

Live demo here

或者,您可以重载相关运算符以隐藏循环/算法调用:

#include <array>
#include <cstddef>

template<std::size_t N>
std::array<bool, N> operator^(const std::array<bool, N>& a, const std::array<bool, N>& b)
{
  std::array<bool, N> c;
  for(std::size_t i = 0; i<N; ++i)
    c[i] = a[i] ^ b[i];

  return c;
}

int main()
{
    std::array<bool,500> a,b,c;
    c = b ^ a;
}

Live demo here。您可以使用算法或您认为合适的任何其他方式编写运算符。

答案 1 :(得分:0)

我想不出任何办法,只能迭代数组。但是你可以一次迭代4(或8)个元素,就像这样(未经测试)。

// Size must be evenly divisible by sizeof(unsigned long)
std::array<char,500> a, b, c;

unsigned long *pa = (unsigned long *)(a.data());
unsigned long *pb = (unsigned long *)(b.data());
unsigned long *pc = (unsigned long *)(c.data());

while (size_t i=0; i<a.size()/sizeof(unsigned long); ++i)
  pc[i] = pa[i] ^ pb[i];

但很难想象这个操作的表现优于bitset

答案 2 :(得分:0)

long a[500/sizeof(long) + 1];
long b[500/sizeof(long) + 1];
long c[500/sizeof(long) + 1];
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));

// init your bitset a and b here

// here is faster than iterating the 500 items array
for(unsigned int i = 0; i < 500/sizeof(long) + 1; i++)
{
    c[i] = a[i] ^ b[i];
}

这里的技巧是 long 在32位机器上是32位,但在64位机器上是64位。

感谢@Adam,我发现boost::dynamic_bitset提供了您需要的精确批处理操作。

答案 3 :(得分:0)

您可能希望重载运算符。

#include <array>
#include <algorithm>
#include <functional>

using barray = std::array<bool, 4>;

barray operator^(barray const &a, barray const &b){
    barray res;
    std::transform(a.begin(), a.end(), b.begin(), res.begin(), std::bit_xor<bool>());

    return res;
}

#include <container_io.h>
#include <iostream>
int main(){
    barray a = {true, true, false, false},
           b = {true, false, true, false};
    std::cout<<(a ^ b)<<"\n";
    return 0;
}

container_io.h是来自http://blog.csdn.net/cqdjyy01234/article/details/19234329的头文件,有助于打印容器。

此外,您可以使用std :: valarray。