c# - 征求意见 : fast hashed base class for dictonary keys

标签 c# performance hash

在我的一个应用程序中,我必须使用许多以自定义对象作为键的字典。为了提高查找的性能,我实现了一个覆盖 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是最好的选择。

最佳答案

  1. 这不是线程安全的。
  2. 如果您只关心引用相等性,为什么要为不同的类型设置不同的计数器?

如果你想要的只是防止哈希被多次计算,为什么不这样(或者如果字典只包含特定类型的对象,则使用泛型的变体):

  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);
        }


    }

编辑:使类与字典兼容

关于c# - 征求意见 : fast hashed base class for dictonary keys,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3430425/

相关文章:

android - LayoutInflater是不是每次都加载xml?

javascript - 如何组织css和js文件的缩小和打包以加快网站速度?

java - 如何查看Java进程中所有线程的所有上下文切换的总和?

ruby - 字符串中最常见的单词

arrays - 反转数组中键、值的顺序转换为哈希

c# - 单元测试 - 绑定(bind)程序集时忽略区域性

c# - 明确的本地范围——有什么真正的好处吗?

python - 通过 Python 对 MySQL 数据库中的密码进行 SHA512 哈希处理

c# - 如何获取从中提取数据的服务器的服务器地址

c# - 控制台中的 WIxsharp 调试自定义操作