我正在研究一种专门的磁盘哈希表(之前的实验与Berkeley,ManagedESENT等没有实现)。它有一个相当简单的链式结构,每个键值对(KVP)在文件中跟随一个长(Int64)值,指向链中的下一个KVP(如果没有一个,则使用零值) )。我正在使用MD5生成哈希码。
在分析代码以评估添加条目的速度时,哈希函数负责大约55%的运行时间,这并不奇怪。但是大约25%的 时间来自binForm.Serialize(ms, obj)
序列化函数中的ObjectToByteArray
调用。两种功能如下所示。我假设我不能在哈希算法本身上获得任何大的收获,但我想知道我是否可以从序列化函数中获得一些性能?
// Compute hash code
long hash(object s)
{
byte[] y = md5.ComputeHash(ObjectToByteArray(s)); // Produces byte[16]
long z = BitConverter.ToInt64(y, 0);
long res = z & bitMask;
return res;
}
// Convert an object to a byte array
private byte[] ObjectToByteArray(Object obj)
{
if (obj == null)
return null;
MemoryStream ms = new MemoryStream();
binForm.Serialize(ms, obj);
return ms.ToArray();
}
答案 0 :(得分:2)
使用protobuf.net,找到here,它的速度要快得多!
<强>更新强>
从查看代码开始,我假设没有任何计算哈希在AppDomains中保持一致的要求?如果不计算你的HashCode可以像下面这样简单:
private static long GenerateHash(object key)
{
long typeHash = key.GetType().GetHashCode();
long keyHash = key.GetHashCode();
return (typeHash << 32) + keyHash;
}
为了将来参考,你的MemoryStream应该在一个使用块中,否则你就有可能泄漏内存:
private byte[] ObjectToByteArray(Object obj)
{
if (obj == null)
return null;
using (MemoryStream ms = new MemoryStream())
{
binForm.Serialize(ms, obj);
return ms.ToArray();
}
}
答案 1 :(得分:0)
二进制格式化器以其性能低下而闻名。尝试其他序列化方法。