vectorの値初期化しないリサイズ

proposal to add vector::push_back_() - std-proposals
Add basic_string::resize_uninitialized (or a similar mechanism) - std-proposals
容量チェックをしないpush_back() - ntnekの日記


std::vectorには、パフォーマンス的に遅くなる部分が2点あります。

  1. リサイズ(コンストラクタ、resizeメンバ関数)によるデフォルトコンストラクタ呼び出し
  2. push_back時のキャパシティチェック

リサイズ操作を行ってリストを大きくすると、大きくした分はデフォルトコンストラクタ呼び出しによって初期化された値が入ります。この初期化がパフォーマンス的に困る場合があります。


そうするとリサイズ操作の代わりに、reserve + push_backを行うことになりますが、push_backには毎回キャパシティチェックのためのif文が入るため、これもものすごい回数呼び出すと、無視できないコストになる場合があります。


つまり、どちらの方法をとるにしても、避けられないコストがあるということです。そのため、値初期化子しないリサイズ操作と、キャパシティチェックをしないpush_backの両方が提案されています。
Boost.Container作者であるIon Gaztañagaさんによると、Boost.Containerは1.55.0時点で内部テスト用に値初期化しないリサイズ操作を持っているとのことです。

vector::vector(size_type, default_init_t);
void vector::resize(size_type, default_init_t);

これは1.55.0時点ではドキュメント化されていませんが、1.56.0にはドキュメントとテストを追加する予定だそうです。


これは、以下のようにして使用します。

#include <iostream>
#include <boost/container/vector.hpp>

int main()
{
    namespace cont = boost::container;

    cont::vector<int> v;
    v.resize(3, cont::default_init);

    for (int x : v) {
        std::cout << x << std::endl;
    }
}
47245192
32755
11222752

リサイズ操作で大きくした場所には、不定値が入っていることがわかります。



宣伝: 『プログラミングの魔導書 Vol.3』 予約受付中です。
http://longgate.co.jp/books/grimoire-vol3.html