在我的一个应用中,我必须使用许多带有自定义对象的dictonarys作为键。为了提高查找的性能,我实现了一个重写GetHashCode的基类。 接缝工作,但不知怎的,我仍然有一个不好的感觉,所以我决定发布我的代码,我会感激任何提示或coments。 (omg我忘记了代码:D)
abstract class FastHashed
{
private static Dictionary<Type,ulong> _instanceCounters = new Dictionary<Type,ulong>();
private int hash;
protected FastHashed()
{
Type instanceType = this.GetType();
if(! _instanceCounters.ContainsKey(instanceType)) _instanceCounters.Add(instanceType,0);
this.hash = ((instanceType.ToString())+(_instanceCounters[instanceType]++.ToString())).GetHashCode();
}
public override int GetHashCode()
{
return hash;
}
}
编辑:如果你不需要,不要乱用哈希。这个“sollution”比默认的GetHashCode()更慢,更不可靠。
编辑: 我使用Equatec分析器和简单的控制台应用程序进行了一些性能测试。
课程计划 { static readonly int cycles = 50000; static Dictionary objectsDict = new Dictionary(); static Dictionary foosDict = new Dictionary();
static void Main(string[] args)
{
foo[] foos = new foo[cycles];
object[] objects = new object[cycles];
for (int i = 0; i < cycles; i++)
{
foos[i] = new foo();
objects[i] = new object();
foosDict.Add(foos[i], i);
objectsDict.Add(objects[i], i);
}
ObjectHash(objects);
FooHash(foos);
}
static void ObjectHash(Object[] objects)
{
int value;
for (int i = 0; i < cycles; i++)
{
value = objectsDict[objects[i]];
}
}
static void FooHash(foo[] foos)
{
int value;
for (int i = 0; i < cycles; i++)
{
value = foosDict[foos[i]];
}
}
class foo
{
private readonly int _hash;
public foo()
{
_hash = this.GetHashCode();
}
public override int GetHashCode()
{
return _hash;
}
}
}
结果: - FooHash 26 774 ms - ObjectHash 7 ms
显然,defhat GetHashCode是最好的选择。
答案 0 :(得分:2)
如果您想要的是防止Hashes多次计算,为什么不这样(或者如果字典只保存某种类型的对象,则为带泛型的变体):
public class ObjectWithCachedHashCode : IEquatable<ObjectWithCachedHashCode>
{
private int _cachedHashCode;
public object Object { get; private set; }
public ObjectWithCachedHashCode(object obj)
{
Object = obj;
_cachedHashCode = obj.GetHashCode();
}
public override int GetHashCode()
{
return _cachedHashCode;
}
public bool Equals(ObjectWithCachedHashCode other)
{
return other!=null && Object.Equals(other.Object);
}
public override bool Equals(object other)
{
return Equals(other as ObjectWithCachedHashCode);
}
}
编辑:使类与Dictionary
兼容答案 1 :(得分:2)
您可以标记哈希变量readonly
。
但说实话,在C#中你有单一继承,“浪费”继承来实现这种特定的行为并不总是明智的。假设您突然想要从“做”某事的基类继承。将类继承保存到建模目的,而不是实现细节。
答案 2 :(得分:0)
据我所知,这在功能上与object.GetHashCode()默认实现等效,除了速度较慢且非线程安全。什么使“快速哈希”变得快速?