5

非常に長いリストをディスクから 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 は、スタック オーバーフローで実際にここで見つけました。

最終的には、数ギガバイトのファイルをロードする必要があります。これが、私がカスタム メモリ マネージャーを使用している理由ですが、この恐ろしい速度低下が受け入れられない理由でもあります。何か案は?

4

1 に答える 1

4

どうぞ。

struct unordered_deref
{
    size_t operator()(const char* p) const
    {
        return hash<string>()(p);
    }
};
于 2011-09-01T00:48:50.440 に答える