非常に長いリストをディスクから unordered_set にロードしています。文字列のセットを使用すると、非常に高速です。約 7 MB のテスト リストが約 1 秒でロードされます。ただし、一連の char ポインターを使用すると、約 2.1 分かかります。
文字列バージョンのコードは次のとおりです。
unordered_set<string> Set;
string key;
while (getline(fin, key))
{
Set.insert(key);
}
char* バージョンのコードは次のとおりです。
struct unordered_eqstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) == 0;
}
};
struct unordered_deref
{
template <typename T>
size_t operator()(const T* p) const
{
return hash<T>()(*p);
}
};
unordered_set<const char*, unordered_deref, unordered_eqstr> Set;
string key;
while (getline(fin, key))
{
char* str = new(mem) char[key.size()+1];
strcpy(str, key.c_str());
Set.insert(str);
}
「new(mem)」は、カスタム メモリ マネージャーを使用しているため、大きなメモリ ブロックを割り当てて、C 文字列などの小さなオブジェクトに割り当てることができます。ただし、これを通常の「新規」でテストしたところ、結果は同じでした。また、メモリマネージャーを他のツールで問題なく使用しました。
アドレスではなく実際の c 文字列に基づいて挿入および検索ハッシュを作成するには、2 つの構造体が必要です。unordered_deref は、スタック オーバーフローで実際にここで見つけました。
最終的には、数ギガバイトのファイルをロードする必要があります。これが、私がカスタム メモリ マネージャーを使用している理由ですが、この恐ろしい速度低下が受け入れられない理由でもあります。何か案は?