私は非常に大きなメモリアドレス(約400.000
)のリストを保持しており、特定のアドレスがすでに400.000回あるかどうかを確認する必要があります。私のセットアップを説明するため値がstlコンテナに既に存在するかどうかを確認する最速の方法
コード例:
std::set<uintptr_t> existingAddresses; // this one contains 400.000 entries
while (true) {
// a new list with possible new addresses
std::set<uintptr_t> newAddresses; // also contains about ~400.000 entries
// in my own code, these represent a new address list
for (auto newAddress : newAddresses) {
// already processed this address, skip it
if (existingAddresses.find(newAddress) != existingAddresses.end()) {
continue;
}
// we didn't have this address yet, so process it.
SomeHeavyTask(newAddress);
// so we don't process it again
existingAddresses.emplace(newAddress);
}
Sleep(1000);
}
これは私が思い付いたし、私はそれを大幅に向上させることができると思う最初の実装です。
次は、データベースでも使用されているカスタムインデックス作成戦略を思いつきました。アイデアは価値の一部をとり、それを使ってそれ自身のグループ・セットでそれを索引付けすることです。私は、例えば、アドレスの最後の2つの数値を取る場合、私は内のアドレスを入れて16^2 = 256
グループを持っているでしょう
[FF] -> all address ending with `FF`
[EF] -> all addresses ending with `EF`
[00] -> all addresses ending with `00`
// etc...
私だけでしょう対応するセットの〜360
のエントリを検索する必要があります。その結果、〜360
のルックアップが400.000回/秒実行されます。ずっといい!
これを行うには、他の方法やより良い方法があるのでしょうか?私の目標は、このアドレス検索を可能な限り高速化することです。
多分[unordered_set](http://en.cppreference.com/w/cpp/container/unordered_set)があなたのために働くことができますか? – slawekwin
@slawekwinこれは、インデックスベースのルックアップを行うよりも、決して高速ではありません。また、 'set'はすでにセットされているので、' set'よりも遅くなると思うので、値の50%をスキップすることができます。これにより検索が高速になります。 –
@SteffenBrem: 'std :: unordered_set'はハッシュベースなので、(理論的に)' set() 'の' O(log n) 'ルックアップよりも優れたスケーリングをしています。実際には、 'std :: vector'の真の' O(1) 'インデックスに比べてオーバーヘッドが少し増加しますが、' O(1) 'にかなり近いはずです。 – ShadowRanger