我想在 C# 中使用驱逐策略构建缓存。我的键是一个字节数组(固定为 32 个字节),值是一个特定类的实例。
我正在讨论最好的方法来做到这一点。我认为这MemoryCache
是要走的路,但它string
用于钥匙。我可以把它变成一个十六进制字符串,但这会产生一些开销。为什么键不是字典中的任意对象?
编写一个字节数组比较器很简单,并且有一个合适的Dictionary
构造函数来提供IEqualityComparer
,但是这种方法并没有免费给我一个驱逐策略。
还有其他我忽略的选择吗?
MemoryCache
实际上在引擎盖下相当复杂(如果你还没有的话,拿一份 Reflector 看看)。它所做的有几件事是不可复制的;其中最主要的是缓存对象使用的近似内存大小。
在性能方面,您将面临比按键按摩更重要的影响。性能是可以接受的,但密钥管理是该过程的一个微不足道的部分。
您可以通过对 aDictionary
与MemoryCache
.
这是一个可以在字节键上使用的小十六进制算法,我已经将其调整为尽可能快。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 );
}
}
那么,一种解决方案是在网络上寻找图书馆。就像一个 LRU 列表。
另一方面,MemoryCache 是经过良好测试和精心设计的。它可能非常快。如果计算字符串键的性能开销是可以接受的,我会选择那个解决方案。我的猜测是计算密钥的开销远低于执行缓存操作,但这是一个猜测(需要测量)。