在DEBUG模式下,DateTime字典更快?

时间:2017-10-04 13:52:17

标签: c# optimization profiling

我试图衡量一些表现,但我偶然发现了一些非常反直觉的结果,我不敢相信。也就是说,在DEBUG模式下查询Dictionary<DateTime> 更快比在RELEASE模式下更快

显然,这个bug必须在我的测量程序中 - 但在哪里?这是:

        Dictionary<DateTime, int> d1 = new Dictionary<DateTime, int>();

        // fill the dictionary
        DateTime now = DateTime.Now;
        const int items = 100000;
        for (int i = 0; i < items; i++)
        {
            DateTime item = now.AddSeconds(-i);
            d1.Add(item, i);
        }
        Console.WriteLine("Items ready");

        const int calls = 100000000;
        DateTime queryDate = DateTime.Now;

        // query the dictionary
        var stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < calls; i++)
        {
            int j;
            if (d1.TryGetValue(queryDate, out j))
            {
                throw new InvalidOperationException();
            }
        }
        stopwatch.Stop();
        Console.WriteLine("{0}ms", stopwatch.ElapsedMilliseconds);

我通过点击Ctl-F5启动此控制台应用程序,因此VS未附加。在我的笔记本电脑上,DEBUG编译版本大约需要1200ms,RELEASE模式大约需要2200ms(!)。

我已经检查过/试过了什么:

  • 项目设置只是VS 2015的默认设置:&#34;优化代码&#34;检查RELEASE但不检查DEBUG。要重现,只需创建一个新的控制台应用项目,然后将代码复制粘贴到Program
  • 当我使用int作为字典的密钥类型来衡量相同的事情时,RELEASE模式 比DEBUG稍快一些。

请帮助揭开我的盲点!

1 个答案:

答案 0 :(得分:1)

VS2015中新项目的默认设置是“首选32位”。对于这个特定的代码,似乎x86抖动表现为次优。

根据Hans Passant的说法:

  

优化器可以做很多事情来改进这段代码。有两种基本方法可以设置TryGetValue()调用的堆栈帧。代码生成器使用一种方式,即通过将参数直接写入堆栈的“现代”方式。但优化器使用另一种方式,即使用PUSH的“旧”方式。效率较低的方式。这是针对x86抖动的,x64抖动没有这个问题。

实际上,切换到64位时,RELEASE模式会像预期的那样稍快一些。