本來想嘗試用 menset
來代替 for
給 vector<bool>
賦初值,看會不會提速,報錯。出錯例程:
#include <cstdio>
#include <vector>
using namespace std;
int main()
{
vector<bool> vb;
vb.reserve(128);
printf("vector<bool> ptr: %p\n", vb.data()); // ERROR
return 0;
}
報錯:
err.cpp: In function 'int main()':
err.cpp:9:44: error: invalid use of void expression
printf("vector<bool> ptr: %p\n", vb.data());
才知道 vector<bool>
是比較特殊的,用位存,而不是 bool 數組,不能照套 vector<int>
的 API。因爲 bitset
不能運行時指定長度,自己寫一個 bitset,順便測試一下性能,跟 vector<bool>
對比:
#include <bits/stdc++.h>
using namespace std;
const int N = 20000000;
struct bool_vec
{
typedef unsigned int dtype;
const int UNIT = sizeof(dtype),
B = 8 * UNIT,
MASK = (1LL << B) - 1;
vector<dtype> vec;
bool_vec(int size)
{
vec.reserve((size + B - 1) / B);
// printf("B: %d, MASK: %x\n", B, MASK);
// printf("wanted size: %d, capacity: %d\n", (size + B - 1) / B, vec.capacity());
}
inline int operator [] (int pos)
{
// return (vec[pos / B] >> (pos % B)) & 1;
return (vec[pos / B] >> (pos & MASK)) & 1;
}
void set(int pos = -1)
{
if (pos >= 0)
{
// vec[pos / B] |= 1 << (pos % B);
vec[pos / B] |= 1 << (pos & MASK);
}
else
memset(vec.data(), 0xff, vec.capacity() * UNIT);
}
void reset(int pos = -1)
{
if (pos >= 0)
{
// vec[pos / B] &= ~(1 << (pos % B));
vec[pos / B] &= ~(1 << (pos & MASK));
}
else
memset(vec.data(), 0, vec.capacity() * UNIT);
}
};
int main()
{
vector<int> vi;
vector<bool> vb;
bool_vec b_vec(N);
double cost;
vi.reserve(N);
vb.reserve(N);
// for int
clock_t start = clock();
for (int *b = vi.data(), *e = vi.data() + N; b < e; )
*b++ = -1;
cost = (double)(clock() - start) / CLOCKS_PER_SEC;
printf("for vector<int>: %f\n", cost);
// memset int
start = clock();
memset(vi.data(), -1, N * sizeof(int));
cost = (double)(clock() - start) / CLOCKS_PER_SEC;
printf("memset vector<int>::data: %f\n", cost);
// for bool
start = clock();
for (int i = 0; i < N; )
vb[i++] = false;
cost = (double)(clock() - start) / CLOCKS_PER_SEC;
printf("for vector<bool>: %f\n", cost);
// for bool_vec
start = clock();
for (int i = 0; i < N; )
b_vec.set(i++); // set 1
cost = (double)(clock() - start) / CLOCKS_PER_SEC;
printf("for bool_vec: %f\n", cost);
puts("--- test 1 ---");
for (int i = 0; i < 200; i += 37)
printf("b_vec[%d]: %d\n", i, b_vec[i]);
// memset int
start = clock();
b_vec.reset(); // set 0
// for (int i = 0; i < N; )
// b_vec.reset(i++); // set 0
printf("memset bool_vec: %f\n", cost);
puts("--- test 0 ---");
for (int i = 0; i < 200; i += 37)
printf("b_vec[%d]: %d\n", i, b_vec[i]);
return 0;
}
結果:
for vector<int>: 0.093191
memset vector<int>::data: 0.007326
for vector<bool>: 0.424405
for bool_vec: 0.136087
--- test 1 ---
b_vec[0]: 1
b_vec[37]: 1
b_vec[74]: 1
b_vec[111]: 1
b_vec[148]: 1
b_vec[185]: 1
memset bool_vec: 0.136087
--- test 0 ---
b_vec[0]: 0
b_vec[37]: 0
b_vec[74]: 0
b_vec[111]: 0
b_vec[148]: 0
b_vec[185]: 0
似乎比 vector<bool> 要快些少,然而比 memset vector<int> 要慢?這是爲什麼?函數也是調的 memset 啊