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

.NET 8下同键扁平集合快速合并为值字典的优化实现

.NET 8 高效合并键值数据实现方案

需求说明

  • 输入为一批对象,每个对象包含:
    • int类型外部键:用于分组的顶级键
    • Dictionary<string, List<double>>类型字典:键为字符串内部键,值为double类型列表
  • 约束:同一外部键下的内部键必须唯一,不可重复
  • 性能要求:适配.NET 8优化,代码每秒执行数次,涉及约20个外部键、3-5个内部键,每个值列表含约100个元素

示例代码

输入示例

var v1 = new { Key = 1, D = new Dictionary<string, List<double>> { { "A", new List<double> { 10, 11 } } } };
var v2 = new { Key = 1, D = new Dictionary<string, List<double>> { { "B", new List<double> { 20, 22 } } } };
var inputItems = new[] { v1, v2 };

期望输出

Dictionary<int, Dictionary<string, List<double>>> mergedResult = new()
{
    [1] = new Dictionary<string, List<double>>
    {
        { "A", new List<double> { 10, 11 } },
        { "B", new List<double> { 20, 22 } }
    }
};

最优实现(单线程场景)

针对.NET 8优化,通过预分配容量、减少字典查找次数实现高效合并:

// 预分配外部字典容量,匹配已知的外部键数量(20)
var mergedResult = new Dictionary<int, Dictionary<string, List<double>>>(20);

foreach (var item in inputItems)
{
    // 一次查找获取或创建内部字典,避免重复ContainsKey判断
    if (!mergedResult.TryGetValue(item.Key, out var innerDict))
    {
        // 预分配内部字典容量,匹配已知的内部键数量(3-5)
        innerDict = new Dictionary<string, List<double>>(5);
        mergedResult.Add(item.Key, innerDict);
    }

    // 遍历当前对象的内部键值对,合并到结果中
    foreach (var (innerKey, values) in item.D)
    {
        // 内部键唯一,直接尝试添加;若需处理重复键可调整逻辑
        innerDict.TryAdd(innerKey, values);
        
        // 若需合并重复内部键的列表(需求不要求则可省略):
        // if (!innerDict.TryAdd(innerKey, values))
        // {
        //     // 预分配列表容量减少扩容开销
        //     innerDict[innerKey].AddRange(values);
        // }
    }
}

优化点说明

  1. 预分配容量:根据已知的键数量初始化字典容量,避免动态扩容带来的内存分配和性能损耗
  2. 高效查找逻辑:使用TryGetValue替代ContainsKey+[]的组合,减少一次字典查找操作
  3. 适配.NET 8特性:.NET 8对Dictionary的枚举、TryGetValue等方法做了性能优化,尤其是值类型键的场景
  4. 内存复用:直接引用输入的列表对象,避免不必要的内存复制;若需数据隔离,可使用new List<double>(values, 100)预分配容量

多线程场景实现(可选)

如果代码涉及多线程写入,可使用ConcurrentDictionary,但单线程场景下不推荐(有额外并发开销):

var mergedResult = new ConcurrentDictionary<int, ConcurrentDictionary<string, List<double>>>(Environment.ProcessorCount, 20);

foreach (var item in inputItems)
{
    var innerDict = mergedResult.GetOrAdd(item.Key, _ => new ConcurrentDictionary<string, List<double>>(Environment.ProcessorCount, 5));
    
    foreach (var (innerKey, values) in item.D)
    {
        innerDict.TryAdd(innerKey, values);
    }
}

内容的提问来源于stack exchange,提问作者Boppity Bop

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:15:13