1

私はデータベースを非常に定期的に照会するアプリケーションを持っています。最大で数百万の文字列が返され、大多数のbiengが繰り返されます。これらのレコードをすべてメモリに保存する必要があり、フットプリントを最小限に抑えようとしています。

私の現在の設計は、すべての文字列に対してGetHashCode()を呼び出し、文字列自体の代わりにハッシュを格納することです。

Dictionary<hashcode,string>()次に、それを構造に追加しようとします。Dictionary<hashcode,count>()また、文字列を使用するエントリが増えるにつれて、インクリメント/デクリメントされる 2番目の辞書も保持します。

エントリdisposeメソッドで、カウンタをデクリメントし、使用量がゼロになったら辞書から文字列を削除します。

だから、いくつかの質問:

これは愚か者の用事ですか?この巨人と一緒に作業するよりも多くの時間と労力を節約できる、使用できるデータ型はありますか?

文字列テーブルをスレッドセーフにしたい(現在はそうではない)。ConcurrentDictinaryを使用するのが最善の策ですか?

前もって感謝します。

4

3 に答える 3

1

これに関する主な問題は、2つの異なる文字列が同じハッシュコードを持つ可能性があることです。

これを必要以上に複雑にしているようです。ここで必要なのは抑留です。

http://msdn.microsoft.com/en-us/library/system.string.intern.aspx

CLRは、メモリを節約するために文字列インスタンスのテーブルをすでに維持しています。

アップデート

ただし、ドキュメントの警告に注意する必要があります。インターンされた文字列は、CLRがアンロードされるまでガベージコレクションされません。つまり、アプリドメインの存続​​期間中はハングします。

ただし、同じパターンを自分でかなり簡単に実装できます。

class LocalStringInterner
{
    private Dictionary<string, string> _strings = new Dictionary<string, string>();

    public string Intern(string str)
    {
        string interned;
        if (_strings.TryGetValue(str, out interned))
            return interned;

        _strings.Add(str, str);
        return str;
    }
}

このようにして、その文字列のセットが不要になったときに、を破棄することができますLocalStringInterner

複数のスレッドから安全に使用できるようにするために、の本体をInternでラップすることができますlock(_strings)

于 2012-12-05T13:54:07.163 に答える
0

Dictionary<hash,string>ハッシュコードを取得して文字列を aに格納し、カウントを別の辞書に格納するポイントがわかりません。文字列自体をキーとして使用でき、辞書はハッシュ コードを自動的に (内部的に) 作成して保存します。したがって、辞書Dictionary<string,count>を 1 つだけ使用するだけで十分です。を介して辞書から文字列を取得することもできますdict.Keys

2 つの異なる文字列のハッシュ コードは同じである可能性があります。これを衝突と呼びます。はDictionary<TKey,TValue>、これらの衝突を自動的に処理します。

ConcurrentDictinary<TKey,TValue>適切なようです。ただし、私はそれについての経験がありません。

于 2012-12-05T14:37:41.613 に答える
0

たぶん、md5-Hash がその手助けになるでしょう。(理論的には) 一意である必要があり、ほとんどのデータベースでサポートされています (そうでない場合は、C# が役立ちます)。

MySQL:

SELECT name, md5(name)
FROM user

そうは言っても、より良いデータベースアプローチを検討します。

サーバー側に文字列ごとに一意の ID がある場合、これは簡単な作業です。

string_resourcesauto_incrementid列とフィールドで呼び出されるテーブルがあるとしvarcharます。valueまた、文字列を 2 回保存しないように、一意のインデックスを追加します。

|id     | value          |
|1      | Hello          |
|2      | World          |
...
|145789 | Something else |

これで、 int 値を辞書に保存できます

md5: 128bit
int32: 32bit  // <-- You Don't Say?
于 2012-12-05T14:06:23.317 に答える