Why might a System.String object not cache its hash code?

后端 未结 6 1870
无人共我
无人共我 2020-12-09 01:34

A glance at the source code for string.GetHashCode using Reflector reveals the following (for mscorlib.dll version 4.0):

public override unsafe int GetHashCo         


        
6条回答
  •  一个人的身影
    2020-12-09 01:51

    Yes, it will cost memory, but what's more important, it will cost memory even if you don't use this feature.

    May be it would be beneficial to have a hashcode-optimized string implementation in framework.

    Anyway, it should be trivial to implement your own:

    public sealed class InternedString : IEquatable
    {
        public InternedString(string s) => String = string.Intern(s);
    
        public string String { get; }
    
        public override bool Equals(object obj) => String.Equals(obj);
    
        public bool Equals(InternedString other) => String.Equals(other?.String);
    
        public override int GetHashCode() => RuntimeHelpers.GetHashCode(String);
    
        public static bool operator ==(InternedString l, InternedString r) =>
            l?.String == r?.String;
    
        public static bool operator !=(InternedString l, InternedString r) => !(l == r);
    }
    

    The idea here is to make sure that each wrapped string is interned, so we can rely on the string references of the same strings inside InternedString to be always the same. This approach optimizes both GetHashCode and Equals calls, making this class a perfect candidate for a Dictionary key.

    The drawback is the cost of interning. Using it everywhere is an overkill. Typical usage scenario is a Dictionary with a few, but very long string keys.

    UPD:

    BTW, I have packaged it, and added a benchmark, check it out.

提交回复
热议问题