哈希表在C#中比C ++更快?

时间:2009-12-13 21:21:11

标签: c# c++ performance hashtable

这是我一直在调查的好奇心。与我继续运行的测试中的STL unordered_map相比,.NET Dictionary类的执行速度非常快,我无法弄清楚原因。

(我机器上0.5秒对4秒) (.NET 3.5 SP1与Visual Studio 2008 Express SP1的STL)

另一方面,如果我在C#和C ++中实现自己的哈希表,C ++版本的速度大约是C#版本的两倍,这很好,因为它强化了我的常识,即本机代码有时更快。 (参见。我说“有时候”。)我是两种语言中的同一个人,我想知道微软的C#编码器能够扮演微软的C ++编码器的伎俩是什么?我无法想象编译器如何能够自己发挥这样的技巧,经历了优化应该将其视为任意函数调用的麻烦。

这是一个简单的测试,存储和检索整数。

C#:

const int total = (1 << 20);
int sum = 0;
Dictionary<int, int> dict = new Dictionary<int, int>();
for(int i = 0; i < total; i++)
{
    dict.Add(i, i * 7);
}

for(int j = 0; j < (1 << 3); j++)
{
    int i = total;
    while(i > 0)
    {
        i--;
        sum += dict[i];
    }
}
Console.WriteLine(sum);

C ++:

const int total = (1 << 20);
int sum = 0;
std::tr1::unordered_map<int, int> dict;
for(int i = 0; i < total; i++)
{
    dict.insert(pair<int, int>(i, i * 7));
}

for(int j = 0; j < (1 << 3); j++)
{
    int i = total;
    while(i > 0)
    {
        i--;
        std::tr1::unordered_map<int, int>::const_iterator found =
            dict.find(i);
        sum += found->second;
    }
}
cout << sum << endl;

3 个答案:

答案 0 :(得分:10)

这两个版本不等价,你在C ++ while循环的每次传递中构造一个迭代器。这会耗费CPU时间并抛出你的结果。

答案 1 :(得分:5)

您正在衡量显式内存管理的成本。我们提供了更多统计信息here.这是relevant too.并且Chris Sells' attempt可以为CLR添加确定性最终结果。

答案 2 :(得分:2)

在代码级别会有一些差异:无序映射采用一对强制构造此类对象的事实,当在Add中传递两个参数时C#可能更快。

另一点是哈希表本身的实现:哈希函数的实现或处理冲突的方法将导致不同的性能模式。

投入对齐和缓存,一些算法的JIT友好性,以及比较两种不同语言的两种不同实现变得非常困难,并且您唯一可以比较的是手头的特定任务。尝试使用更少或更多的元素,或尝试随机访问元素而不是按顺序访问元素,您可能会看到非常不同的结果。