字典的关键性能

时间:2011-04-21 11:32:34

标签: .net performance dictionary

string密钥比int中的Dictionary<,>密钥更快?

2 个答案:

答案 0 :(得分:20)

没有。首先,Dictionary [UPDATED]使用密钥的哈希码在其内部存储中找到它们 - 而不是密钥。 Hashcode是int 。对于int,它只是int的值,因为string必须生成它。

所以使用int 稍微更快。


事实上,为字符串生成哈希代码是一个非常复杂的过程(使用Reflector的代码段)[希望这不会被视为版权漏洞,因为它不是]:

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

答案 1 :(得分:5)

我知道这是个很老的问题,可以回答,所以对于以后寻找它的每个人来说,都是这样。对我来说,这也是一个有趣的问题,我试图找到该问题的实际答案,结果也很有趣。

通常,将String作为键要比int作为键慢得多。

代码:

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

结果:

enter image description here