導入
C++17以前、2つのstd::mapを結合しようとすると、一方の要素を一つずつinsert関数でコピーまたはムーブする必要がありました。これはコードが冗長になるだけでなく、結合元のコンテナに同じキーが存在する場合のオーバーヘッドも無視できませんでした。C++17から導入された「merge」関数を使えば、ノードの付け替え(ポインタの繋ぎ変え)のみで高速かつ簡潔に結合が可能です。このTipsを習得して、コンテナ操作のパフォーマンスを最適化しましょう。
基礎知識
std::mapは内部で「二分探索木(赤黒木など)」というデータ構造を持っています。各要素は「ノード」と呼ばれる単位で管理されており、merge関数はこのノード自体の所有権を移動させる仕組みです。
従来のinsertでは、新しいキーに対して新しいノードのメモリ確保が発生していましたが、mergeは既存のノードをそのまま移動先のツリーに組み込むため、メモリ割り当てのコストがかかりません。これが「高速」である最大の理由です。
実装/解決策
merge関数は、引数として渡されたコンテナ(ソース)から、移動先のコンテナ(デスティネーション)にキーが重複しない要素をすべて移動させます。
もし、移動先に同じキーが存在する場合、その要素は移動されずソース側に残ります。この特性を利用することで、マージ後の競合を簡単にチェックできます。
サンプルプログラム
以下のコードは、2つのマップを統合し、結果を確認する実用的な例です。
include
include
コメント