.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); // } } }
优化点说明
- 预分配容量:根据已知的键数量初始化字典容量,避免动态扩容带来的内存分配和性能损耗
- 高效查找逻辑:使用
TryGetValue替代ContainsKey+[]的组合,减少一次字典查找操作 - 适配.NET 8特性:.NET 8对
Dictionary的枚举、TryGetValue等方法做了性能优化,尤其是值类型键的场景 - 内存复用:直接引用输入的列表对象,避免不必要的内存复制;若需数据隔离,可使用
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
相关产品推荐
相关产品推荐

