C# 高效处理海量数据:解决嵌套并行的性能陷阱
问题场景
假设我们需要在 10万条ID 和 1万个目录路径 中,快速找到所有满足以下条件的路径:
- 路径本身包含ID字符串
- 该路径的子目录中也包含同名ID
初始代码采用Parallel.ForEach嵌套Task.Run,但在实际运行时发现:
- 内存占用飙升到8GB以上
- CPU利用率仅30%左右
- 程序运行10分钟后无响应
原始问题代码分析
var safeList = new ConcurrentBag<string>();
Parallel.ForEach(ids, id => {
var tasks = paths.Select(path => Task.Run(() => {
// 问题点1:每次遍历都执行磁盘I/O
var subDirs = Directory.GetDirectories(path, "*", SearchOption.AllDirectories);
// 问题点2:低效字符串匹配
if (path.Contains(id)) safeList.Add(path);
// 问题点3:嵌套并发导致资源争抢
var matches = subDirs.Where(dir => dir.Contains(id)).ToList();
safeList.AddRange(matches);
}));
Task.WaitAll(tasks.ToArray());
});
三大性能杀手
- 重复磁盘扫描:每个Task都执行
GetDirectories,百万次I/O操作拖慢速度 - 无节制线程创建:
ids.Length * paths.Length产生上亿个Task,线程池崩溃 - 低效集合操作:频繁操作
ConcurrentBag引发锁竞争
四步优化方案
通过以下优化,实测处理时间从 10分钟+ 降至 8秒,内存占用稳定在1GB内!
第一步:缓存磁盘结构(I/O优化)
// 预加载所有路径的目录结构
var dirCache = new Dictionary<string,

最低0.47元/天 解锁文章
368

被折叠的 条评论
为什么被折叠?



