専門分野はありませんが、引き続きご利用いただけます。(遅いですが)
しかし、これが私が見つけたトリックで、プロキシクラスを使用してを有効std::fill
にします。std::vector<bool>
std::_Vbase
(警告:MSVC2013でのみテストしたため、他のコンパイラでは動作しない可能性があります。)
int num_bits = 100000;
std::vector<bool> bit_set(num_bits , true);
int bitsize_elem = sizeof(std::_Vbase) * 8; // 1byte = 8bits
int num_elems = static_cast<int>(std::ceil(num_bits / static_cast<double>(bitsize_elem)));
ここでは、要素のビットを使用する場合は要素のビット全体が必要になるため、要素の数を切り上げる必要があります。
この情報を使用して、ビットの基になる元の要素を指すポインターのベクトルを作成します。
std::vector<std::_Vbase*> elem_ptrs(num_elems, nullptr);
std::vector<bool>::iterator bitset_iter = bit_set.begin();
for (int i = 0; i < num_elems; ++i)
{
std::_Vbase* elem_ptr = const_cast<std::_Vbase*>((*bitset_iter)._Myptr);
elem_ptrs[i] = elem_ptr;
std::advance(bitset_iter, bitsize_elem);
}
(*bitset_iter)._Myptr
:のイテレータを逆参照することにより、プロキシクラスとそのメンバーにstd::vector<bool>
アクセスできます。reference
_Myptr
の戻り型はですので、std::vector<bool>::iterator::operator*()
その恒常性を。const std::_Vbase*
で 削除const_cast
します。
これで、これらのビットの基になる元の要素を指すポインタを取得しますstd::_Vbase* elem_ptr
。
elem_ptrs[i] = elem_ptr
:このポインタを記録します、..。
std::advance(bitset_iter, bitsize_elem)
:...そして、前の要素によって保持されているビットをジャンプすることによって、次の要素を見つけるために私たちの旅を続けます。
std::fill(elem_ptrs[0], elem_ptrs[0] + num_elems, 0); // fill every bits "false"
std::fill(elem_ptrs[0], elem_ptrs[0] + num_elems, -1); // fill every bits "true"
std::fill
これで、ビットのベクトルではなく、ポインターのベクトルを使用できるようになりました。
おそらく、プロキシクラスを外部で使用することに不快感を覚えたり、プロキシクラスの恒常性を取り除いたりする人もいるかもしれません。
しかし、それを気にせず、何かを速くしたい場合は、これが最速の方法です。
以下でいくつかの比較を行いました。(新しいプロジェクトを作成しました。構成、リリース、x64は何も変更されていません)
int it_max = 10; // do it 10 times ...
int num_bits = std::numeric_limits<int>::max(); // 2147483647
std::vector<bool> bit_set(num_bits, true);
for (int it_count = 0; it_count < it_max; ++it_count)
{
std::fill(elem_ptrs[0], elem_ptrs[0] + num_elems, 0);
} // Elapse Time : 0.397sec
for (int it_count = 0; it_count < it_max; ++it_count)
{
std::fill(bit_set.begin(), bit_set.end(), false);
} // Elapse Time : 18.734sec
for (int it_count = 0; it_count < it_max; ++it_count)
{
for (int i = 0; i < num_bits; ++i)
{
bit_set[i] = false;
}
} // Elapse Time : 21.498sec
for (int it_count = 0; it_count < it_max; ++it_count)
{
bit_set.assign(num_bits, false);
} // Elapse Time : 21.779sec
for (int it_count = 0; it_count < it_max; ++it_count)
{
bit_set.swap(std::vector<bool>(num_bits, false)); // You can not use elem_ptrs anymore
} // Elapse Time : 1.3sec
注意点が1つあります。swap()
元のベクトルを別のベクトルと一緒にすると、ポインターのベクトルは役に立たなくなります。