在我的一个应用程序中,我必须使用许多以自定义对象作为键的字典。为了提高查找的性能,我实现了一个覆盖 GetHashCode 的基类。它似乎可以工作,但不知何故我仍然对此有一种不好的感觉,所以我决定发布我的代码,如果有任何提示或评论,我将不胜感激。(天哪,我忘了密码 :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;
}
}
编辑:如果没有必要,请不要弄乱散列。这种“解决方案”比默认的 GetHashCode() 更慢且更不可靠。
编辑:我使用 Equatec 分析器和一个简单的控制台应用程序进行了一些性能测试。
类(class)计划 { 静态只读 int 周期 = 50000; static Dictionary objectsDict = new 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 毫秒 - ObjectHash 7 毫秒
显然默认的GetHashCode是最好的选择。
- 这不是线程安全的。
- 如果您只关心引用相等性,为什么要为不同的类型设置不同的计数器?
如果你想要的只是防止哈希被多次计算,为什么不这样(或者如果字典只包含特定类型的对象,则使用泛型的变体):
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);
}
}
编辑:使类与字典兼容
我是一名优秀的程序员,十分优秀!