You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 9.0.6中FrozenDictionary迭代速度慢于普通Dictionary的原因排查求助

.NET 9.0.6中FrozenDictionary迭代速度慢于普通Dictionary的原因排查求助

最近我了解到FrozenDictionary<TKey, TValue>有着专门优化的实现,目标是让读操作(包括查找和枚举)尽可能快,不像普通ImmutableDictionary那样只是简单包装Dictionary。刚好我手头有个计算密集型应用,里面用到的集合加载后就不会再变更,所以想实际测试下它的性能表现。

我用BenchmarkDotNet编写了如下测试代码:

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Linq;

[MemoryDiagnoser]
public class DictionaryVsFrozenDictionaryBenchmarks
{
    private KeyValuePair<string, string>[] _source;
    private Dictionary<string, string> _dictionary;
    private FrozenDictionary<string, string> _frozen;
    private string _middleKey;
    private string _middleKeyPlusOne;

    [Params(10, 100, 10_000)]
    public int Size;

    [GlobalSetup]
    public void Setup()
    {
        _source = Enumerable.Range(0, Size)
             .Select(i => new KeyValuePair<string, string>($"Key{i}", $"Value{i}"))
             .ToArray();
        _middleKey = $"Key{Size / 2}";
        _middleKeyPlusOne = $"Key{Size / 2 + 1}";
        _dictionary = new Dictionary<string, string>(_source);
        _frozen = _dictionary.ToFrozenDictionary();
    }

    [Benchmark]
    public Dictionary<string, string> Dictionary_Create() => new Dictionary<string, string>(_source);

    [Benchmark]
    public FrozenDictionary<string, string> FrozenDictionary_Create()
    {
        return new Dictionary<string, string>(_source).ToFrozenDictionary();
    }

    [Benchmark]
    public string Dictionary_Read1() => _dictionary[_middleKey];

    [Benchmark]
    public string FrozenDictionary_Read1() => _frozen[_middleKey];

    [Benchmark]
    public string Dictionary_Read2() => _dictionary[_middleKeyPlusOne];

    [Benchmark]
    public string FrozenDictionary_Read2() => _frozen[_middleKeyPlusOne];

    [Benchmark]
    public int Dictionary_Iteration()
    {
        int count = 0;
        foreach (var kvp in _dictionary)
        {
            count += kvp.Value.Length;
        }
        return count;
    }

    [Benchmark]
    public int FrozenDictionary_Iteration()
    {
        int count = 0;
        foreach (var kvp in _frozen)
        {
            count += kvp.Value.Length;
        }
        return count;
    }
}

public class Program
{
    public static void Main(string[] args)
    {
        BenchmarkRunner.Run<DictionaryVsFrozenDictionaryBenchmarks>();
    }
}

测试环境如下:

  • BenchmarkDotNet v0.14.0
  • Windows 11 (10.0.26100.4351)
  • AMD Ryzen 9 7900,1 CPU,24逻辑核心/12物理核心
  • .NET SDK 9.0.301,运行时.NET 9.0.6,X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI

得到的基准测试结果如下:

MethodSizeMeanErrorStdDevGen0Gen1Gen2Allocated
Dictionary_Create1083.758 ns0.3282 ns0.2909 ns0.0262--440 B
FrozenDictionary_Create10507.064 ns7.0749 ns5.9079 ns0.1144--1920 B
Dictionary_Read1106.816 ns0.0298 ns0.0279 ns----
FrozenDictionary_Read1103.936 ns0.0256 ns0.0239 ns----
Dictionary_Read2106.896 ns0.0410 ns0.0363 ns----
FrozenDictionary_Read2103.923 ns0.0256 ns0.0239 ns----
Dictionary_Iteration105.698 ns0.0231 ns0.0216 ns----
FrozenDictionary_Iteration109.033 ns0.0107 ns0.0095 ns----
Dictionary_Create100744.981 ns4.7618 ns4.4542 ns0.18690.0010-3128 B
FrozenDictionary_Create1005,195.994 ns61.6515 ns57.6689 ns0.90790.0381-15288 B
Dictionary_Read11006.379 ns0.0219 ns0.0183 ns----
FrozenDictionary_Read11004.988 ns0.1318 ns0.1518 ns----
Dictionary_Read21006.345 ns0.1527 ns0.1192 ns----
FrozenDictionary_Read21005.257 ns0.1066 ns0.0891 ns----
Dictionary_Iteration10058.236 ns0.6178 ns0.4824 ns----
FrozenDictionary_Iteration10082.735 ns1.6026 ns1.9077 ns----
Dictionary_Create10000191,494.816 ns3,777.4265 ns5,768.5296 ns76.904376.904376.9043283068 B
FrozenDictionary_Create10000634,803.685 ns12,458.2875 ns15,755.7460 ns227.5391210.9375199.21881210740 B
Dictionary_Read1100007.748 ns0.0930 ns0.0776 ns----

从结果里能看到,读操作确实比普通Dictionary快,但迭代速度却明显落后——Size=10的时候甚至慢了50%左右。我有点搞不懂,是不是我的测试代码哪里写得有问题?还是这个情况和CPU型号有关?有没有大佬能帮忙分析下原因?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 11:18:05