C #: оптимизация доступа к словарю (хэш в ключевых структурах) - PullRequest
1 голос
/ 20 июня 2010

Итак, мне нужно создать структуру в C #, которая будет выступать в качестве ключа в (довольно большом) словаре, будет выглядеть так:

private readonly IDictionary<KeyStruct, string> m_Invitations;

Проблема в том, что мне ДЕЙСТВИТЕЛЬНО нужна структура дляиспользуйте в качестве ключа, потому что можно идентифицировать записи только через два отдельных элемента данных, где один из них может быть пустой (не только пустой!) строкой.

Что мне нужно будет реализовать в структуре?Как бы вы занялись созданием хеша?Может ли коллизия хешей (иногда) сильно повлиять на производительность или это будет незначительно?

Я спрашиваю, потому что это код "внутреннего цикла".

Ответы [ 3 ]

5 голосов
/ 20 июня 2010

Если у вас есть резарпер, вы можете сгенерировать этот метод с помощью Alt-Ins -> Элементы равенства.

Вот сгенерированный код для вас 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);
    }
}
3 голосов
/ 20 июня 2010

Если KeyStruct является структурой (объявленной с ключевым словом struct C #), не забудьте переопределить методы кода Equals и GetHash или предоставить собственный IEqualityComparer для конструктора словаря, потому что реализация метода ValueType.Equals по умолчанию использует Reflection для сравнения содержимого двухэкземпляры структуры.

Предпочтительно сделать KeyStruct неизменным, если вы это сделаете, вы можете вычислить хеш экземпляра структуры один раз, а затем просто вернуть его из метода GetHashCode.Но это может быть преждевременной оптимизацией, в зависимости от того, как часто вам нужно получать значение по ключу.

Как правило, можно использовать структуру в качестве ключа словаря.

Или, возможно, вы спрашиваетекак реализовать метод GetHashCode?

2 голосов
/ 20 июня 2010

Вам необходимо реализовать (переопределить) два метода.
1. bool Equals(object)
2. int GetHashCode()

Хеш-код не обязательно должен быть уникальным, но чем меньше разных объектов,тот же хэш-код, тем лучше будет производительность.

вы можете использовать что-то вроде:

public int GetHashCode()
{
    int strHash = str == null ? 0 : str.GetHashCode();
    return ((int)lng*397) ^  strHash;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...