如何优化处理大数据集的双层foreach循环以缩短运行时间
循环优化方案
核心问题分析
当前代码是双重嵌套循环,时间复杂度为O(n*m)(n≈7.5万,m≈70万),这是导致耗时极长的根本原因。同时每次循环内重复执行Split(','),额外增加了不必要的性能开销。
具体优化步骤
1. 预处理Excel数据集,构建哈希字典
将newExcelList的数据提前拆分,用excelparts[0]作为键存入字典,把内层的线性查找转为O(1)的哈希查找:
// 预处理newExcelList,跳过前3行构建字典 var excelDict = new Dictionary<string, string[]>(); foreach (string j in newExcelList.Skip(3)) { string[] excelparts = j.Split(','); // 若存在重复键,可根据需求调整(示例保留第一个出现的项) if (!excelDict.ContainsKey(excelparts[0])) { excelDict[excelparts[0]] = excelparts; } }
2. 遍历文本数据集,直接通过字典匹配
遍历dataText时仅拆分一次,直接从字典中查找匹配项,彻底消除嵌套循环:
foreach (string i in dataText.Skip(1).OrderBy(x => x.Split(',')[0])) { string[] textparts = i.Split(','); if (excelDict.TryGetValue(textparts[0], out var excelparts)) { sw.WriteLine($"{excelparts[0]}\tN25\tPRIM\t{excelparts[1]}\t{excelparts[2]}\t{excelparts[3]}\t{excelparts[4]}\t"); } }
3. 额外性能优化点
- 减少排序时的重复拆分:原排序逻辑会对每个元素执行一次
Split,可改为先拆分再排序,降低重复操作:var sortedData = dataText.Skip(1) .Select(x => x.Split(',')) .OrderBy(parts => parts[0]); foreach (var textparts in sortedData) { if (excelDict.TryGetValue(textparts[0], out var excelparts)) { sw.WriteLine($"{excelparts[0]}\tN25\tPRIM\t{excelparts[1]}\t{excelparts[2]}\t{excelparts[3]}\t{excelparts[4]}\t"); } } - 优化IO写入:如果
sw是StreamWriter,可设置AutoFlush = false,批量写入后再调用Flush(),减少磁盘IO的频繁操作。
优化效果预估
优化后时间复杂度降至O(n + m),总耗时可从63小时大幅压缩到几分钟级别(具体时长取决于硬件性能,但性能提升幅度会非常显著)。
内容的提问来源于stack exchange,提问作者WigSnatcher
相关产品推荐
相关产品推荐

