如何优化双层foreach循环的执行时长?附子索赔关联代码片段
优化双层foreach循环以提升子索赔关联列表的获取性能
首先看你这段代码的核心问题:每次遍历都做线性查找(Where),导致时间复杂度很高——假设processedClaims有M个元素,newClaimLink有N个,claims有K个,原代码的时间复杂度是O(MN + MK),数据量一大就会明显变慢。
优化思路:用哈希字典替代线性遍历
我们可以提前把需要频繁查找的数据集转换成字典(哈希表),这样每次查找的时间复杂度降到O(1),整体时间复杂度能优化到O(M + N + K),性能提升非常明显。
优化后的代码
// 提前构建两个字典,避免重复遍历 // 1. 把ClaimLink按ClaimLinkId分组,直接拿到对应的ClaimId列表 var claimLinkByParentId = newClaimLink .GroupBy(link => link.ClaimLinkId) .ToDictionary(group => group.Key, group => group.Select(link => link.ClaimId).ToList()); // 2. 把claims转成Id为键的字典,快速查找单个Claim var claimById = claims.ToDictionary(claim => claim.Id); // 遍历processedClaims,填充子索赔列表 foreach (var claim in processedClaims) { claim.Children ??= new List<Claim>(); // 简化空判断,C# 8.0+可用 // 直接从字典取当前claim对应的子ClaimId列表,找不到就跳过 if (claimLinkByParentId.TryGetValue(claim.Id, out var childClaimIds)) { foreach (var childId in childClaimIds) { // 从字典快速获取子Claim,存在就添加到Children if (claimById.TryGetValue(childId, out var childClaim)) { claim.Children.Add(childClaim); } } } }
额外优化点说明
- 用
??=运算符简化空列表的初始化(C# 8.0及以上支持),如果是旧版本可以保留原有的if (claim.Children == null)判断。 - 用
TryGetValue替代Where+Any的组合,既避免了不必要的集合遍历,也处理了键不存在的情况,代码更健壮。 - 提前分组和构建字典的操作只需要执行一次,而不是在每次循环里重复做,这是性能提升的关键。
内容的提问来源于stack exchange,提问作者Chamara Madhamperuma
相关产品推荐
相关产品推荐

