去地图vs C#字典

时间:2016-01-28 07:14:55

标签: c# performance go

我写了一个快速而肮脏的测试来检查Go vs C#在并发查找访问方面的性能,并对结果感到惊讶。

这是一个非常简单的例子,我不是专家,但测试只是在地图上执行1,000,000次锁定/检查/添加/解锁操作,它只是单线程,因为我正在检查这些功能:< / p>

from django.utils.text import Truncator
s = "<div>Please truncate this</div>"
Truncator(s).words(2, html=True)

在C#中也是如此(通过LINQPad):

truncate = "read more %(truncated_text)s"
Truncator(s).words(2, html=True,truncate=truncate)

我总结两个集合的元素以确保它们匹配(499,999,500,000)并打印所花费的时间。结果如下:

  • C#:56ms
  • Go:327ms

我已经检查过无法初始化地图的大小,只能初始化容量,所以我想知道是否有什么办法可以改善Go地图的性能?

没有地图访问权限需要Go 32ms来执行1,000,000次锁定/解锁操作。

4 个答案:

答案 0 :(得分:5)

  

[S] o我想知道我是否可以采取任何措施来改善围棋地图的表现?

不,没有。 Go基本上没有性能旋钮。

(请注意,Go的map类型是一个非常通用且强大的哈希映射,它使用强加密哈希(如果可能)来防止攻击并强制随机键/迭代顺序。它是&#34 ;完全是通用的&#34;而不只是&#34;快速字典&#34;。)

完全正确:环境变量GOGC到&#34;调和&#34; GC

答案 1 :(得分:3)

可能有一件事被忽视,并将整个练习转化为苹果和橙子:同步。在Go端,您使用Mutex,每次访问时都会转到内核。在C#端,你使用lock(){},它使用SpinLock的组合,只在需要时回退到内核调用。由于您的测试无论如何都是在单个线程中执行的,因此C#甚至不会进入内核。

在Go中不鼓励使用Mutex,而是应该使用通道进行同步。

一些建议: 1.如果要自己对地图/字典进行基准测试,请删除同步。 2.如果您希望对并发性能进行基准测试,请使用正确的构造和范例编写测试。

干杯!

答案 2 :(得分:1)

我使用Mono编译了你的C#示例,并在OS X上运行它,只是为了中和任何&#34;魔法&#34;微软可能已将其添加到Windows的Windows实现中。

对于这个特定的测试来说,C#确实比Go快,除非我们忽略了一些Go性能技巧:

dict.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;

public class DictionaryTest
{
    public static void Main()
    {
        var cache = new Dictionary<int, int>(1000000);
        var sw = Stopwatch.StartNew();

        for (var i = 0; i < 1000000; i++)
        {
            lock (cache)
            {
                int d;
                if (cache.TryGetValue(i, out d) == false)
                {
                    cache.Add(i, i);
                }
            }
        }

        sw.Stop();

        Console.WriteLine(string.Format("{0}ms", sw.ElapsedMilliseconds));

        var sum = 0L;
        foreach (var kvp in cache)
        {
            sum += kvp.Value;
        }

        Console.WriteLine("Sum: " + sum);
    }
}

如果您安装了Mono SDK,则可以使用mcs dict.cs编译上述内容并使用mono dict.exe执行。

我运行了几次,平均需要47毫秒,而Go版本的平均值为149毫秒。

答案 3 :(得分:1)

我发现如果将1000000缩小到100000,golang速度将从151.0087ms更改为10.0005ms(15.1乘以),而csharp版本从65ms更改为9ms(7.22乘以),因此这意味着golang的哈希图难以处理较大的地图?

我写了一个简单的go基准测试程序

    new Vue({
    //'#app' is the name of the parent componenet
    el: '#app',
    methods:{
      // The e (can be any letter or word) here is the value that was emitted by the
      // child(base-checkbox) to the parent(app)...and this case the value is Boolean
      lovingVue(e){
        console.log(e)
      }
    }
    })

我得到了结果

func BenchmarkIntMapGet100(b *testing.B) {
    count := 100
    setupIntMap(b, count)

    b.ResetTimer()
    for i:=0; i<b.N; i++{
        _, _ = intMap[i%count]
    }
}