【发布时间】:2014-01-31 20:31:22
【问题描述】:
关于 STL std::bitset - 它的文档说函数 set/reset/test 进行边界检查,而 operator[] 没有。我的计时实验表明,set/test 函数的执行速度通常比operator[] 快 2-3%。我正在使用的代码是:
typedef unsigned long long U64;
const U64 MAX = 800000000ULL;
struct Bitmap1
{
void insert(U64 N) {this->s[N % MAX] = 1;}
bool find(U64 N) const {return this->s[N % MAX];}
private:
std::bitset<MAX> s; // <---- takes MAX/8 memory (in bytes)
};
struct Bitmap2
{
void insert(U64 N) {this->s.set(N % MAX);}
bool find(U64 N) const {return this->s.test(N % MAX);}
private:
std::bitset<MAX> s; // <---- takes MAX/8 memory (in bytes)
};
int main()
{
Bitmap2* s = new Bitmap2();
// --------------------------- storing
const size_t t0 = time(0);
for (unsigned k = 0; k < LOOPS; ++k)
{
for (U64 i = 0; i < MAX; ++i) s->insert(i);
}
cout << "storing: " << time(0) - t0 << endl;
// -------------------------------------- search
const size_t t1 = time(0);
U64 count = 0;
for (unsigned k = 0; k < LOOPS; ++k)
{
for (U64 i = 0; i < MAX; ++i) if (s->find(i)) ++count;
}
cout << "search: " << time(0) - t1 << endl;
cout << count << endl;
}
如何解释?没有边界检查应该可以为我们节省一些周期,对吧?
Compiler: g++ 4.8.1 (options -g -O4)
VMware VM: Ubuntu 3.11.0-15
Host: MacBook Pro
【问题讨论】:
-
可能是基准测试错误。请发布完整的示例。
-
你做了哪些具体的实验?你能告诉我们你尝试了什么,你使用了什么编译器和编译器标志,以及结果吗?
-
@AlekseyYakovlev:
Bitset::operator[]必须创建和使用代理。Bitset::Set不需要做这样的事情。我希望Set实际上远更快,但由于分配 100MB 数据的缓存,差异会丢失。 -
使用 bitset 非常便宜,以至于您的测试完全由 rand 甚至 % 运算符主导,这实际上是一个非常慢的除法。这意味着您的基准测试对编译器更改有关不相关代码的内容非常敏感。您没有以有效的方式进行基准测试。首先修复基准。
-
@MooingDuck - 我的意思是二进制大小爆炸性增长导致的二阶效应,这里公式化linuxjournal.com/article/7269
标签: c++ performance stl bitset