私はこの問題に使用する最良のデータ構造を理解しようとしています。私は文字列であるキーを持つキーバリューストアを実装しています。値は頻繁に追加され、通常は1〜2回だけ検索されます。当初はstd::map
を使用しましたが、キーを追加して赤黒のツリーを再調整するオーバーヘッドが値の検索にかかる時間の減少を隠していたため、パフォーマンスが最適でないことがわかりました。現在、私は変更された単一リンクリストを使用しています。これは、c文字列(const char *)、バイト単位の長さ、および格納された値を含む構造体を使用します。キーを使って値を見つけたいときは、リストを繰り返してキーの大きさを比較します。一致すれば、memcmpを使って文字列が同じかどうかを調べます。それらが同一であれば、私はその値を返します。私はstd::map
以上でこの方法を使って約10倍のパフォーマンスを達成することができました。しかし、私はそれを約2倍効率化する必要があります。誰もこの問題のために、より良いタイプのデータ構造を推薦できますか?どのデータ構造を使用すればいいですか
答えて
実際の問題に関する知識がなくても、高速なソリューションを提供することは困難です。特に、あなたのデータセットはどれくらいの大きさですか、実際のデータはどこに保存されていますか(コンテナや他の場所に保存されていますか?)。コンテナで実行する必要がある他の操作は何ですか?コンテナから要素を削除する必要がありますか?
他の質問の1つにコメントすると、キーはstd::unordered_map
にコピーする必要があると述べています。キーが既に別の場所に保存されている場合は、マップを使用するようアドバイスしますが、 。キーとして使用するポインタ、および間接参照にカスタムコンパレータと結果で動作:ポインタの代わりに、これはコピーを取り除くかかるだろう、実際の文字列を格納することにより
// Assuming that the data is stored in std::string somewhere else
struct custom_compare {
bool operator()(std::string* lhs, std::string* rhs) const {
return lhs!=rhs && (lhs->size() < rhs->size() || lhs->compare(*rhs) < 0);
}
};
std::map< std::string*, data, custom_compare > mymap;
。カスタムコンパレータは基本的にリストに実装されているものと同じ速さで、ツリーは内容のバランスをとってO(ログn)ルックアップを可能にします。セットのサイズに応じて(多くの要素がある場合)、線形検索よりも改善されますが、サイズが小さいと線形検索が改善されます。
また、データの多様性に応じて、線形検索に従うこともできますが、計算時間が短縮され、同時にセットをできるだけ均等に分割するいくつかの基準に応じて検索スペースを分割することもできます。たとえば、線形検索を使用できますが、単一のリストを保持する代わりに、キーの長さに基づいて異なるリストを保持します。
基準が実際に文字列の内容(文字ではなく文字)に基づいている場合は、トライの定義に近似しています。すでに実装されているライブラリを取得した場合や、必要な時間を費やしたい場合は、このタイプのルックアップの最速のコンテナの1つになります。これは、 "size"変数を要素を文字列の長さに置き換えます。
ありがとうございます。私はあなたがstd :: mapでカスタムコンパレータを使用できるかどうかはわかりませんでした。 –
おそらく何らかの種類のハッシュテーブルですか?あなたのキーに良いハッシュアルゴリズムを使用すると、検索時間が大幅に短縮されます。あなたの挿入時間は少し遅くなりますが、うまくいけば、あなたのハッシュ関数が良い場合は大したことではありません。
@RTS: 'std :: unordered_map'(ハッシュテーブル)とtestで' std :: map'(rbtree)を置き換えるのはかなり簡単です。私は自分のコードで 'std :: unordered_map'のパフォーマンスにとても満足しています。 – Blastfurnace
@Blastfurnance:私はすでにstd :: unordered_mapとstd :: tr1 :: unordered_mapを試していますが、これはリンクされたリストソリューションよりも私のユースケースでは遅いです。彼らはキーデータのコピーを必要としたので、リンクされたリストでは、私は単に文字列ポインタをコピーすることができました。 –
std::vector
は、リンクされたリストよりも高速で、でも高速です。ほとんどの場合、メモリの割り当ては不要です。
あなたはあなたのタグの1つとして持っています...なぜTrieを使用しないのですか?挿入が迅速でなければならず、文字の重複によりメモリ使用量が低下し、検索が高速になります。
- 1. ここで使用するデータ構造はどれですか?
- 2. ジオコーディングに使用するデータ構造はどれですか?
- 3. 使用するC#データ構造体はどれですか?
- 4. 配列の構造はどうすればいいですか?
- 5. どのC#データ構造を使用すべきですか?
- 6. Rubyデータ構造を.js.erbを使用したjavascriptデータ構造に変換するにはどうすればよいですか?
- 7. 構造体内に多くの構造体を入れるにはどうすればいいですか?
- 8. 他のデータ構造体の値としてredisのデータ構造体を設定するにはどうすればいいですか?
- 9. Union/Findデータ構造をKruskalのアルゴリズムに適用するにはどうすればよいですか?
- 10. どのデータ構造を使用するか
- 11. 一部のメンバーだけが別の構造体の値を使用できる構造体を宣言するにはどうすればいいですか?
- 12. CSSでカラーホイール構造を作るにはどうすればいいですか?
- 13. Rails - アプリビューファイルを構造化するにはどうすればいいですか?
- 14. マルチレベルドリルダウンTableViewのデータ構造を作成するにはどうすればいいですか?
- 15. スタックとキューのデータ構造を解決するにはどうすればいいですか?
- 16. 構造体のデータを更新してチェーンコードに保存するにはどうすればいいですか?
- 17. Visual Studioコードで使用されているデータ構造
- 18. Webサイトから構造化データ(XML)と.docxを送るにはどうすればいいですか?
- 19. C#でDLLImportを構造体のパラメータとして使用するにはどうすればよいですか?
- 20. 階層構造のレコードでFileHelpersを使用するにはどうすればよいですか?
- 21. 構造体へのポインタとして構造体をマーシャリングするにはどうすればよいですか?
- 22. プロトコルとしてタイプされたSwift汎用データ構造で弱い参照を使用するにはどうすればよいですか?
- 23. Rustマルチスレッドサーバーで使用できる構造を作成するにはどうすればよいですか?
- 24. .NETを使用してウェブサイトのディレクトリ構造をトラバースするにはどうすればよいですか?
- 25. アンドロイドのMVP構造を使用してrecyclerviewをリフレッシュするにはどうすればよいですか?
- 26. 構造体を使用してこのコードを短縮するにはどうすればよいですか?
- 27. Skype情報を構造化データに追加するにはどうすればいいですか?
- 28. テンプレートで使用する構造指示プロパティをエクスポートするにはどうすればよいですか?
- 29. このデータ構造からグラフを作成するにはどうすればよいですか?
- 30. Goの構造属性として「型」を使用するにはどうすればよいですか?
いくつの要素がありますか?キーの平均サイズは? –