4

我想在 C# 中使用驱逐策略构建缓存。我的键是一个字节数组(固定为 32 个字节),值是一个特定类的实例。

我正在讨论最好的方法来做到这一点。我认为这MemoryCache是要走的路,但它string用于钥匙。我可以把它变成一个十六进制字符串,但这会产生一些开销。为什么键不是字典中的任意对象?

编写一个字节数组比较器很简单,并且有一个合适的Dictionary构造函数来提供IEqualityComparer,但是这种方法并没有免费给我一个驱逐策略。

还有其他我忽略的选择吗?

4

2 回答 2

3

MemoryCache实际上在引擎盖下相当复杂(如果你还没有的话,拿一份 Reflector 看看)。它所做的有几件事是不可复制的;其中最主要的是缓存对象使用的近似内存大小。

在性能方面,您将面临按键按摩更重要的影响。性能是可以接受的,但密钥管理是该过程的一个微不足道的部分。

您可以通过对 aDictionaryMemoryCache.

这是一个可以在字节键上使用的小十六进制算法,我已经将其调整为尽可能快。BCL 还包含 base 16 功能(我在编写此代码时不知道这些功能,我一直保留它,因为它更简单/更快)。

正如评论中所指出的,byte[]除非密钥将在其他地方使用,否则甚至可能不需要将其转换为十六进制来满足规定的要求。

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

那么,一种解决方案是在网络上寻找图书馆。就像一个 LRU 列表。

另一方面,MemoryCache 是经过良好测试和精心设计的。它可能非常快。如果计算字符串键的性能开销是可以接受的,我会选择那个解决方案。我的猜测是计算密钥的开销远低于执行缓存操作,但这是一个猜测(需要测量)。

于 2012-05-21T22:07:33.227 回答