如何在数组<bool>上使用位操作
How to use bitoperations on array<bool>
对于一些性能敏感的项目(执行时间很关键,内存不是问题),我需要某种容器,它可以容纳中等大小(最多500个)的布尔值。大小在编译时是已知的,因此似乎有两个明显的选择:
bitset<500>
和array<bool,500>
在这些容器上,程序必须进行大量的位操作并读取/设置单个值。
到目前为止,我使用的是位集,但[]-运算符读取/设置元素的性能非常糟糕。由于数组明显优于这里的位集,所以我所需要的只是在这些数组上使用逻辑运算符的某种快速方法。
所以我想要的是:
array<bool,500> a,b,c;
c = b ^ a; // ??? how to do it, need & and ^
我想应该有一些魔术用memcpy或类似的东西来做…但直到现在我都想不通。对整个数组进行迭代不是一种选择。(试过了,太慢了)
如果你不介意内存分配,你可以使用std::valarray
,它有元素二进制运算符:
#include <valarray>
int main()
{
std::valarray<bool> a(500),b(500),c(500);
c = b ^ a;
}
现场演示。
或者,您可以重载相关运算符以隐藏循环/算法调用:
#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;
}
现场演示。您可以使用算法或任何其他您认为合适的方式编写运算符。
我想不出任何方法,只能迭代数组。但您可能能够一次迭代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
实现。
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提供了您所需要的精确批量操作。
您可能需要重载运算符。
#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。
相关文章:
- 对字符串进行位操作
- 对字符数组中的元素执行逐位操作
- 逐位操作的隐式类型转换
- 如何进行特定的位操作?
- C++避免位操作完全移位
- 使用双包装器类进行位操作(C++、clang)修复性能下降问题
- 使用位操作优化检查
- 子集相关位操作
- 使用 c++ 提升库的按位操作
- 位操作和异或
- 位操作将最左侧的设置位转换为右侧交替位?
- 为什么对小于 4 个字节的整数类型的位操作会发生意外行为?
- POD 类型的原子按位操作
- 如何使用位操作在单个整数中编码和解码两个数字
- __int128的位操作
- 使用位操作会影响内存消耗?
- 在具有位操作的函数中获得值
- C/C 位操作不会导致预期输出
- 在数组大小中使用位操作的原因
- 了解C++位操作中的二进制转换实现