简体   繁体   English

C#:优化字典访问(键结构中的哈希)

[英]C#: optimizing dictionary access (hash in key structures)

So, I need to create a struct in C# that will act as a key into a (quite large) dictionary, will look like this: 因此,我需要在C#中创建一个结构,该结构将充当(很大)字典的键,如下所示:

private readonly IDictionary<KeyStruct, string> m_Invitations;

Problem is, I REALLY need a struct to use as a key, because it is only possible to identify entries via two separate data items, where one of them can be a null (not only empty!) string. 问题是,我真的需要一个结构用作键,因为只能通过两个单独的数据项来标识条目,其中一个可以是空(不仅是空!)字符串。

What will I need to implement on the struct? 我需要在该结构上实现什么? How would you go about creating the hash? 您将如何创建哈希? Would a hash collision (occassional) hurt the performance heavily or would that be negligible? 哈希冲突(偶尔发生)会严重影响性能还是可以忽略不计?

I'm asking because this is "inner loop" code. 我问,因为这是“内循环”代码。

If you have resharper, you can generate these method with Alt-Ins -> Equality members. 如果您有共享工具,则可以使用Alt-Ins-> Equality成员生成这些方法。

Here is the generated code for you KeyStruct: 这是您为KeyStruct生成的代码:

public struct KeyStruct : IEquatable<KeyStruct>
{
    public string Value1 { get; private set; }
    public long Value2 { get; private set; }

    public KeyStruct(string value1, long value2)
        : this()
    {
        Value1 = value1;
        Value2 = value2;
    }

    public bool Equals(KeyStruct other)
    {
        return Equals(other.Value1, Value1) && other.Value2 == Value2;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (obj.GetType() != typeof (KeyStruct)) return false;
        return Equals((KeyStruct) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return ((Value1 != null ? Value1.GetHashCode() : 0)*397) ^ Value2.GetHashCode();
        }
    }

    public static bool operator ==(KeyStruct left, KeyStruct right)
    {
        return left.Equals(right);
    }

    public static bool operator !=(KeyStruct left, KeyStruct right)
    {
        return !left.Equals(right);
    }
}

If KeyStruct is structure (declared with struct C# keyword), don't forget to override Equals and GetHash code methods, or provide custom IEqualityComparer to dictionary constructor, because default implementation of ValueType.Equals method uses Reflection to compare content of two structure instances. 如果KeyStruct是结构体(使用struct C#关键字声明),请不要忘记重写Equals和GetHash代码方法,或者为字典构造函数提供自定义IEqualityComparer,因为ValueType.Equals方法的默认实现使用Reflection来比较两个结构实例的内容。

It is prefer to make KeyStruct immutable, if you do so, you can calculate structure instance hash once and then simply return it from GetHashCode method. 最好使KeyStruct不可变,如果这样做,则可以一次计算结构实例哈希,然后只需从GetHashCode方法返回它即可。 But it may be premature optimization, depends of how often do you need to get value by key. 但这可能是过早的优化,取决于您需要多长时间通过键来获取价值。

Generally, it is OK to use structure as a dictionary key. 通常,可以使用结构作为字典键。

Or maybe you are asking how to implement GetHashCode method? 或者,也许您在问如何实现GetHashCode方法?

You need to implement (override) two methods. 您需要实现(覆盖)两种方法。
1. bool Equals(object) 1. bool Equals(object)
2. int GetHashCode() 2. int GetHashCode()

The hash code need not be unique but the less different objects will return the same hash code the better performance you will have. 哈希码不必是唯一的,但是不同的对象返回相同的哈希码的次数越少,您将获得更好的性能。

you can use something like: 您可以使用类似:

public int GetHashCode()
{
    int strHash = str == null ? 0 : str.GetHashCode();
    return ((int)lng*397) ^  strHash;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM