4

C# でエビクション ポリシーを使用してキャッシュを構築したいと考えています。私のキーはバイト配列 (32 バイト固定) で、値は特定のクラスのインスタンスです。

これを行う最善の方法を議論しています。私はそれMemoryCacheが行く方法だと思っていますが、それはstringキーに使用されます。これを 16 進文字列に変換できますが、オーバーヘッドが発生します。キーが辞書のような任意のオブジェクトではないのはなぜですか?

バイト配列比較子を作成するのは簡単で、Dictionaryを提供する適切なコンストラクターがありますIEqualityComparerが、このアプローチでは無料でエビクション戦略を得ることができません。

私が見落としている他のオプションはありますか?

4

2 に答える 2

3

MemoryCache実際には内部はかなり複雑です (Reflector のコピーを入手して、まだ見ていない場合は参照してください)。複製するのが簡単ではないことがいくつかあります。これらの中で最も重要なのは、キャッシュされたオブジェクトが使用するメモリ サイズを概算することです。

パフォーマンスに関しては、キーのマッサージよりもはるかに重大な影響と戦うことになります。パフォーマンスは許容範囲ですが、キー管理はプロセスの重要な部分ではありません。

この違いは、 aDictionaryに対して100K+ の追加操作を実行することで確認できますMemoryCache

これは、可能な限り高速になるように調整した、バイトキーで使用できる小さな 16 進アルゴリズムです。BCL には、base 16 の機能も含まれています (このコードを書いたときは知りませんでしたが、単純で高速なのでそのままにしておきました)。

コメントに記載されているようにbyte[]、キーが他の場所で使用されない限り、16 進数への変換は、記載されている要件を満たすために必要でさえない可能性があります。

public unsafe sealed class Hex
{
    private static readonly char[] _hexRange = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    /// <summary>
    /// Converts a byte array into a string of base-16 values.
    /// </summary>
    /// <param name="value">Value to convert.</param>
    /// <returns>Base-16 encoded string.</returns>
    public static string ToHexString( byte[] value )
    {
        char* buffer = stackalloc char[( value.Length * 2 ) + 1]; // +1 for null terminator
        char* start = buffer;

        for( int i = 0; i < value.Length; i++ )
        {
            *buffer++ = _hexRange[value[i] / 16];
            *buffer++ = _hexRange[value[i] % 16];
        }

        return new string( start );
    }
}
于 2012-05-22T04:25:13.297 に答える
1

解決策の 1 つは、Web でライブラリを探すことです。LRU リストのように。

一方、MemoryCache は十分にテストされ、適切に設計されています。かなり速い可能性が高いです。文字列キーを計算するパフォーマンスのオーバーヘッドが許容できる場合は、そのソリューションを使用します。私の推測では、キーの計算はキャッシュ操作を行うよりもオーバーヘッドがはるかに少ないと思いますが、それは推測です (測定する必要があります)。

于 2012-05-21T22:07:33.227 に答える