高性能ハッシュマップデータ構造で値を構造化するには、プリミティブキー(int、おそらくlong)をマップする必要があります。
私のプログラムにはこれらのマップが数百あり、各マップには通常最大で数千のエントリがあります。ただし、マップは常に「更新」または「チャーン」されます。何百万もの処理を想像addし、delete第二のメッセージ。
CまたはC ++のどのライブラリが、このユースケースに適合するデータ構造を持っていますか?または、独自に構築することをどのように推奨しますか?ありがとう!
高性能ハッシュマップデータ構造で値を構造化するには、プリミティブキー(int、おそらくlong)をマップする必要があります。
私のプログラムにはこれらのマップが数百あり、各マップには通常最大で数千のエントリがあります。ただし、マップは常に「更新」または「チャーン」されます。何百万もの処理を想像addし、delete第二のメッセージ。
CまたはC ++のどのライブラリが、このユースケースに適合するデータ構造を持っていますか?または、独自に構築することをどのように推奨しますか?ありがとう!
@roe:追加/削除操作は、取得操作よりもはるかに(100倍)頻繁です。
回答:
Google SparseHash(またはC11バージョンのGoogle SparseHash-c11)を試して、ニーズに合っているかどうかを確認することをお勧めします。これらには、メモリ効率の高い実装と、速度が最適化された実装があります。私はずっと前にベンチマークを行いましたが、それは速度の点で利用可能な最高のハッシュテーブル実装でした(ただし欠点はあります)。
CまたはC ++のどのライブラリが、このユースケースに適合するデータ構造を持っていますか?または、独自に構築することをどのように推奨しますか?ありがとう!
LGPLのJudyアレイをチェックしてください。自分自身を使用したことはありませんが、いくつかの機会に私に宣伝されました。
STLコンテナ(std :: hash_mapなど)のベンチマークを試すこともできます。プラットフォーム/実装およびソースコードの調整(動的メモリ管理にはできるだけ多くの費用がかかる)によっては、十分なパフォーマンスが得られる可能性があります。
また、最終的なソリューションのパフォーマンスがソリューションのコストよりも優れている場合は、すべてをプレーンアレイに配置するのに十分なRAMを備えたシステムを注文することができます。インデックスによるアクセスのパフォーマンスは無敵です。
追加/削除操作は、取得操作よりもはるかに(100倍)頻繁です。
これは、最初にアルゴリズムの改善に集中することをお勧めします。データが書き込まれるだけで、読み取られない場合、なぜそれらをまったく書き込むのですか?
マルチスレッドプログラムを使用している場合は、Intelスレッドビルディングブロックライブラリにいくつかの便利なハッシュテーブルがあります。たとえば、tbb :: concurrent_unordered_mapのAPIはstd :: unordered_mapと同じですが、主な機能はスレッドセーフです。
Facebookの愚かなライブラリも見てください。高性能の同時ハッシュテーブルとスキップリストがあります。
Androidソースから(したがって、Apache 2ライセンス)
https://github.com/CyanogenMod/android_system_core/tree/ics/libcutils
hashmap.cを見て、include / cutils / hashmap.hを選択します。スレッドセーフが必要ない場合は、ミューテックスコードを削除できます。サンプルの実装は、libcutils /str_parms.cにあります。
まず、libmemcacheなどの既存のソリューションがニーズに合っているかどうかを確認します。
そうでない場合...
ハッシュマップはあなたの要件に対する明確な答えのようです。キーに基づいてo(1)ルックアップを提供します。最近のほとんどのSTLライブラリは、ある種のハッシュを提供しています。したがって、プラットフォームが提供するものを使用してください。
その部分が完了したら、ソリューションをテストして、デフォルトのハッシュアルゴリズムがニーズに対して十分なパフォーマンスを発揮するかどうかを確認する必要があります。
そうでない場合は、ネット上にあるいくつかの優れた高速ハッシュアルゴリズムを調べる必要があります
これが十分でない場合は、自分でハッシュモジュールをロールすることができます。これにより、テストしたSTLコンテナーで発生した問題と、上記のハッシュアルゴリズムの1つが修正されます。結果は必ずどこかに投稿してください。
ああ、複数のマップがあるのは興味深いことです...おそらく、キーを64ビットnumとして使用し、上位ビットを使用して、それが属するマップを区別し、すべてのキーと値のペアを1つの巨大なハッシュに追加することで簡略化できます。基本的な素数ハッシュアルゴリズムで10万個程度のシンボルが完全に機能するハッシュを見てきました。
そのソリューションが何百ものマップと比較してどのように機能するかを確認できます..メモリプロファイリングの観点からはより良いと思います...この演習を行うことができたら、結果をどこかに投稿してください
ハッシュアルゴリズムよりも、メモリの継続的な追加/削除(回避できるか?)と、アプリケーションのパフォーマンスにとってより重要なCPUキャッシュ使用プロファイルである可能性があると思います。
幸運を
その他のコンテナテンプレートのハッシュテーブルを試してください。ITSはclosed_hash_map、Googleのと同じ速度についてですdense_hash_mapが、使用(含まれる値に制限なし)に容易になり、同様他のいくつかの特典があります。
http://incise.org/hash-table-benchmarks.htmlgccの実装は非常に優れています。ただし、非常に悪い標準的な決定を尊重する必要があることに注意してください。
再ハッシュが発生すると、すべてのイテレータは無効になりますが、個々の要素への参照とポインタは引き続き有効です。実際の再ハッシュが発生しない場合、変更はありません。
http://www.cplusplus.com/reference/unordered_map/unordered_map/rehash/
これは基本的に、標準では実装はリンクリストに基づいている必要があると述べていることを意味します。パフォーマンスが向上するオープンアドレス法を防ぎます。
グーグルスパースはオープンアドレッシングを使用していると思いますが、これらのベンチマークでは、高密度バージョンのみが競合他社を上回っています。ただし、スパースバージョンは、メモリ使用量のすべての競合を上回ります。(また、プラトーがなく、要素の数が純粋な直線です)