序文として申し分なく、めったに変更されないデータの比較的小さなサブセットをキャッシュして、パフォーマンス上の理由でデータベースに頻繁にクエリを実行しないようにする必要があります。このデータは、他のテーブルのはるかに大きなデータセットによって頻繁に参照されるため、読み取り専用で頻繁に使用されます。
キャッシュされたオブジェクトを更新するためのスレッドセーフコールバックメカニズムと共にコミットの変更をリッスンしながら、基本的に問題の2つのテーブル全体をメモリに保存する機能を持つクラスを作成しました。
現在の実装には、各テーブルの要素に対して2つのstd::vectors
1つがあります。このクラスは、各ベクトル全体へのアクセスと、std::find
、std::find_if
などを介してテーブルデータの特定の要素を検索するための便利なメソッドの両方を提供します。
std::list
、std::set
、またはstd::map
over std::vector
を使用して検索することをお勧めしますか?ほとんどの場合、新しい接続が作成されたときにデータベースから1回移入された後、これらのコンテナに要求されます。
また、VS2010またはBoostでサポートされているC++ 0x機能を使用することもできます。
特定の値を検索するには、std::set
とstd::map
を使用するとO(log N)時間かかりますが、他の2つの値を検索するにはO(N) time; 、std::set
またはstd::map
の方がおそらく優れていますC++ 0xにアクセスできるため、平均して一定の時間がかかるstd::unordered_set
またはstd::unordered_map
を使用することもできます。
find_if
については、任意の述語が必要であり、コンテナが任意に最適化できないため、それらの間にはほとんど違いがありません。
ただし、特定の述語でfind_if
を頻繁に呼び出す場合は、自分で最適化できます。カスタムコンパレータまたは特殊キーでstd::map
またはstd::set
を使用し、find
を使用します代わりに。
std::lower_bound
を使用して並べ替えられたベクトルは、頻繁に更新しない場合はstd::set
と同じくらい高速です。両方ともO(log n)です。どちらが自分の状況に適しているかを確認することは両方とも試してみる価値があります。
(拡張)要件から複数のフィールドを検索する必要があるため、Boost.MultiIndexを指定します。
このBoostライブラリを使用すると、oneコンテナー(含まれる各要素の1つの例のみ)を構築し、任意の数のインデックスにインデックスを付けることができます。また、使用するインデックスを正確に指定できます。
使用するインデックスの種類を決定するには、広範なベンチマークが必要です。 500
はエントリ数が比較的少ないため、一定の要因はうまく機能しません。さらに、シングルスレッドとマルチスレッドの使用には顕著な違いがあります(ほとんどのハッシュテーブル実装は、線形リハッシュを使用しないため、MT使用で崩壊する可能性があります。スレッドはテーブルを再ハッシュし、他のすべてをブロックします)。
パフォーマンスの違いが目立たないか、単に重要ではない場合、範囲要求(Abc
で始まるすべての名前)に対応するために、ソートされたインデックス(可能であればスキップリストのような)をお勧めします。
試して。それは非常に簡単で、STLでコンテナはほとんど交換可能です。
テーブル内の特定の1つの列のみを個別の値として検索する場合は、std::hash
が最速です。
いくつかの異なる述語を使用して検索できるようにするには、何らかのインデックス構造が必要になります。現在のベクターベースのアプローチを、検索するフィールドごとに1つずつ、複数のハッシュテーブルまたはマップで拡張することで実装できます。値は、ベクターへのインデックス、またはベクター内の要素への直接ポインターです。
さらに進んで、7月に日付があるすべての機会など、範囲を検索できるようにするには、範囲を抽出できる順序付けられたデータ構造が必要です。
Stlではありませんが、市販のc ++コンテナは、検索、削除、変更にO(1)が含まれ、挿入中にO(logn).