Key performance for a dictionary

2020-02-13 07:38发布

Is a string key faster than a int key in a Dictionary<,>?

2条回答
够拽才男人
2楼-- · 2020-02-13 08:04

I know this is pretty old and answered question, so this answer for everybody who look for it in future. Also for me it was interesting question and I tried to find practical answer to this question, and result is pretty interesting.

Generally String as key is much slower than int as key.

Code:

class Program
{
    object obj = new object();

    Dictionary<long, object> longDict = new Dictionary<long, object>();
    Dictionary<string, object> stringDict = new Dictionary<string, object>();

    public static void Main(string[] args)
    {
        Program hash = new Program();

        hash.Test(1000);
        hash.Test(10000);
        hash.Test(100000);
        hash.Test(1000000);
        hash.Test(10000000);

        Console.Read();
    }

    private void Test(int iterations)
    {
        Console.WriteLine(String.Format("Test for {0} iterations", iterations));

        longDict.Clear();
        stringDict.Clear();

        for (int i = 0; i < iterations; i++)
        {
            longDict.Add(i, obj);
        }

        for (int i = 0; i < iterations; i++)
        {
            stringDict.Add(i.ToString(), obj);
        }

        IntTest(iterations);
        StringTest(iterations);
    }

    private void IntTest(int iteraions)
    {
        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
        stopwatch.Start();

        object test;

        for (int i = 0; i < iteraions; i++) {
            test = longDict[i];
        }

        stopwatch.Stop();
        Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
    }

    private void StringTest(int iteraions)
    {
        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
        stopwatch.Start();

        object test;

        for (int i = 0; i < iteraions; i++)
        {
            test = stringDict[i.ToString()];
        }

        stopwatch.Stop();
        Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);
    }
}

Result:

enter image description here

查看更多
时光不老,我们不散
3楼-- · 2020-02-13 08:06

No. First of all, Dictionary [UPDATED] uses hash code of the keys to find them in its internal storage - rather than the keys. And Hashcode is an int. For int, it is just the value of the int, for string it has to be generated.

So using int is slightly faster.


In fact generating hash code for a string is a pretty complex process (snippet using Reflector) [Hope this is not taken as copyright breach because it is NOT]:

fixed (char* str = ((char*) this))
{
    char* chPtr = str;
    int num = 0x15051505;
    int num2 = num;
    int* numPtr = (int*) chPtr;
    for (int i = this.Length; i > 0; i -= 4)
    {
        num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
        if (i <= 2)
        {
            break;
        }
        num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
        numPtr += 2;
    }
    return (num + (num2 * 0x5d588b65));
}
查看更多
登录 后发表回答