访问和更改长布尔数组的最快实现是什么?
What is the fastest implementation for accessing and changing a long array of boolean?
我想实现一个很长的布尔数组(作为二进制基因组),并访问一些间隔来检查该间隔是否全部为真,此外,我想改变一些间隔值,
例如,我可以创建4个表示:
boolean binaryGenome1[10e6]={false};
vector<bool> binaryGenome2; binaryGenome2.resize(10e6);
vector<char> binaryGenome3; binaryGenome3.resize(10e6);
bitset<10e6> binaryGenome4;
并以这种方式访问:
inline bool checkBinGenome(long long start , long long end){
for(long long i = start; i < end+1 ; i++)
if(binaryGenome[i] == false)
return false;
return true;
}
inline void changeBinGenome(long long start , long long end){
for(long long i = start; i < end+1 ; i++)
binaryGenome[i] = true;
}
vector<char>
和normal boolean array
(ass将每个布尔值存储在一个字节中)似乎都是一个糟糕的选择,因为我需要在空间中高效。但是vector<bool>
和bitset
有什么区别呢?
在其他地方我读到向量有一些开销,因为你可以选择它的大小和编译时间-"开销"是什么-访问?开销是多少?
我想使用CheckBinGenome()
和changeBinGenome()
多次访问数组元素,最快的实现是什么?
使用std::bitset是最好的。
如果在编译时知道数据的长度,则考虑使用std::array<bool>
或std::bitset
。后者可能更节省空间(您必须衡量访问时间中相关的额外工作是否超过减少缓存压力带来的速度增益—这将取决于您的工作负载)。
如果你的数组长度不固定,那么你需要一个std::vector<bool>
或std::vector<char>
;还有boost::dynamic_bitset
,但是我从来没用过。
如果您将一次更改大的区域,就像您的示例所暗示的那样,构造您自己的表示并直接操作底层存储可能是值得的,而不是通过迭代器一次操作一位。例如,如果使用char
的数组作为基础表示,那么将大范围设置为0或1主要是memset()
或std::fill()
调用,只计算范围开始和结束处的值。在尝试之前,我会先从一个简单的实现和一组良好的单元测试开始。
对于std::vector<bool>
、std::array<bool>
和/或std::bitset
的迭代器,你的标准库有专门的算法版本(至少在理论上)是可能的,它们完全可以完成上面的工作,或者你可以编写和贡献这样的专门化。如果可能的话,这是一条更好的道路——世界可能会感谢你,你也会分担一些维护的责任。
重要提示
如果使用std::array<bool>
,您需要注意,与其他std::array<>
实例化不同,它不实现标准容器语义。这并不是说它不应该被使用,但要确保你了解它的缺点!
,检查所有元素是否为true
我真的不确定这是否会给我们带来比加速更多的开销。实际上,我认为现在的CPU可以做到这一点相当快,你真的遇到了一个糟糕的性能?(或者这只是你真正问题的一个骨架?)
#include <omp.h>
#include <iostream>
#include <cstring>
using namespace std;
#define N 10000000
bool binaryGenome[N];
int main() {
memset(binaryGenome, true, sizeof(bool) * N);
int shouldBreak = 0;
bool result = true;
cout << result << endl;
binaryGenome[9999995] = false;
bool go = true;
uint give = 0;
#pragma omp parallel
{
uint start, stop;
#pragma omp critical
{
start = give;
give += N / omp_get_num_threads();
stop = give;
if (omp_get_thread_num() == omp_get_num_threads() - 1)
stop = N;
}
while (start < stop && go) {
if (!binaryGenome[start]) {
cout << start << endl;
go = false;
result = false;
}
++start;
}
}
cout << result << endl;
}
- 实现无开销push_back的最佳方法是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 私有在函数定义/实现的返回值范围内是什么意思 (c++)?
- 在 c++ 或 python 中生成一个体面的视差图以在 Raspberry Pi 上实现的最佳方法(算法或函数)是什么
- 在 C++17 中实现迭代器和const_iterator的正确方法是什么?
- 十进制到二进制的实现不能完全适用于我大学的检查器。问题或提示可能是什么
- 实现此自定义priority_queue的正确方法是什么
- 实现此"on error, throw"回调的最佳方法是什么?
- 在QGraphicsView上实现交互式样条曲线的最佳方法是什么?
- 当您知道结构将来会更改时,实现结构读写的最佳方法是什么
- std :: is_nothrow_copy_copy_constructible的实现是什么?
- 具有多态数据的容器的常见实现是什么
- RWTPtrOrderedVector的替代实现是什么
- 将一元函数应用于向量的某些元素的良好实现是什么?
- 向量类中擦除函数的正确实现是什么
- 映射到ASCII的Character的底层实现是什么?
- c++中标准的延迟/终结器实现是什么?
- 访问和更改长布尔数组的最快实现是什么?
- 单例类的确切用法和实现是什么?