ファイルからmap
に読み込むデータが大量にあります。マップからシリアライズされているため、並べ替え順になっています。 最初にデータをvector
にロードしてから、map
に一括ロードしてinsert
にする方が早いことがわかりました。これにより、19秒の読み込み時間でわずか1秒を節約できます。STL map :: insertサポートはmove_iteratorsでセマンティクスを移動する必要がありますか?
value_type
は、他の構造のベクターを含む構造体です。ロードが完了した後でvector
は必要ないので、私はmap::insert
への呼び出しでmove_iterator
を使用します。 MSVC 2015(VC14)を使用すると、データはマップに移動されず、代わりにconst_reference
を介してSTLコードの内側にコピーされます。
これはデータの移動を無視するための標準準拠の実装ですか?
template<typename Stream, typename Key, typename Type, typename Traits, typename Allocator>
bool const read(Stream &is, std::map<Key, Type, Traits, Allocator> &map)
{
size_t size;
read(is, size);
std::vector<std::pair<Key, Type>> items(size);
for (size_t i=0; i<size; ++i)
{
auto &item = items[i];
if (!read(is, item.first) || !read(is, item.second))
return false;
}
map.insert(std::make_move_iterator(items.begin()), std::make_move_iterator(items.end()));
return !!is;
}
私は
for (auto &item : items)
map.insert(std::move(item));
でmap.insert
を交換し、問題を克服しましたが、それはとてもきちんとしていないが、別の0.6秒を保存しません。
これは 'std :: vector'に当てはまりますが、マップに挿入するためのものではありません。 –
それは本当ではありません。私は彼らがstd :: vectorを例として挙げたと信じています:)ここに別のリンクhttp://en.cppreference.com/w/cpp/language/move_constructorがあります。注意部分は言う:強力な例外保証を可能にするために、ユーザー定義の移動コンストラクターは例外をスローするべきではありません。実際、標準コンテナは通常、コンテナ要素を再配置する必要があるときに、moveとcopyの間で選択するためにstd :: move_if_noexceptに依存します。 – klimov
@klimov: gcc std :: libを生きている人と議論していることに注意してください! :-) –