DateTime字典在调试模式下更快



我正在尝试衡量某些性能,但我偶然发现了一些我拒绝相信的非常违反直觉的结果。也就是说,在调试模式下查询Dictionary<DateTime>比在发行模式下更快。

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

        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。在我的笔记本电脑上,我在发行模式下的调试版本和2200ms(!)大约获得1200ms。

我已检查/尝试的内容:

  • 项目设置只是VS 2015的默认设置:"优化代码"已选中以进行发布,但不能进行调试。要复制,只需创建一个新的控制台应用程序项目,然后将代码复制到Program中。
  • 当我用int作为字典的关键类型测量相同的内容时,发行模式 比预期的debug稍快。

请帮助发现我的盲点!

VS2015中新项目的默认设置为"优先32位"。对于此特定的代码,似乎X86抖动表现出色。

根据汉斯·帕克(Hans Passant)的说法:

优化器无法做到改进此代码。可以设置TryGetValue()调用的堆栈框架有两种基本方法。代码生成器通过将参数直接写入堆栈来使用一种方式,即"现代"方式。但是优化器使用另一种方式,使用推送的"旧"方式。效率较低的方法。这是特定于x86抖动的,x64抖动没有这个问题。

的确,切换到64位,发布模式的速度略高于预期。

最新更新