2012-05-21 25 views
4

我想用C#中的驱逐策略构建高速缓存。我的密钥是一个字节数组(固定为32字节),值是特定类的实例。用byte []键构建C#高速缓存,并逐出策略

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

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

我忽略了其他选项吗?

+3

嗯,使用Convert.ToBase64String并继续你的生活。 –

+0

我有同样的问题,在我的情况下,它稍差,因为我想要一个真正通用的MemoryCache,可以有任何类型的密钥。 在我的情况下创建了一个使用MemoryCache的类,但它也必须提供密钥转换方法。 从来没有像我想要的那么好,但我不想尝试复制MemoryCache在引擎盖下做的一些复杂的事情。 在我已经完成的新应用程序中,我们只使用字典实现了定时缓存并覆盖了Get和Set方法。这样你就可以使用任何东西作为一个键。 –

回答

3

MemoryCache实际上是相当复杂的(引用Reflector的副本,如果你还没有看看)。它有几件事情是非常重要的,其中最主要的是近似缓存对象使用的内存大小。

从表现上看,您将与竞争更多更重要的影响比按键的一个关键。性能是可以接受的,但是关键管理是这个过程中不重要的一部分。

您可以通过在DictionaryMemoryCache之间执行100K +添加操作来查看此差异。

这里有一个小的十六进制算法,你可以使用你的字节键,我已经调整了尽可能快。 BCL还包含基本的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); 
    } 
} 
+0

如果你正在做不安全的代码,为什么要转换为十六进制呢? Pin'value',将指针转换为'char *'并使用String(char * value,int startIndex,int length)构造函数构造一个字符串。 –

+0

我使用十六进制来生成安全/一致的值(用于URL等目的),但您的建议可能对OP更有意义。用于MemoryCache的密钥可以是任何字符串。 –

1

那么,一种解决方案是在网上寻找一个库。像一个LRU列表。

另一方面,MemoryCache经过良好测试和精心设计。它可能会非常快。如果计算字符串键的性能开销是可以接受的,那么我只需要使用该解决方案。我的猜测是,计算密钥的开销比执行缓存操作要少得多,但这是一种猜测(需要衡量)。

+1

我想我可能会高估字符串键计算的代价。我会等一会儿,看看是否有其他人唧唧喳喳,但我喜欢你的回答 – jglouie