C# 高效处理海量数据:解决嵌套并行的性能陷阱


C# 高效处理海量数据:解决嵌套并行的性能陷阱


问题场景

假设我们需要在 10万条ID1万个目录路径 中,快速找到所有满足以下条件的路径:

  1. 路径本身包含ID字符串
  2. 该路径的子目录中也包含同名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());
});
三大性能杀手
  1. 重复磁盘扫描:每个Task都执行GetDirectories,百万次I/O操作拖慢速度
  2. 无节制线程创建ids.Length * paths.Length产生上亿个Task,线程池崩溃
  3. 低效集合操作:频繁操作ConcurrentBag引发锁竞争

四步优化方案

通过以下优化,实测处理时间从 10分钟+ 降至 8秒,内存占用稳定在1GB内!


第一步:缓存磁盘结构(I/O优化)
// 预加载所有路径的目录结构
var dirCache = new Dictionary<string, 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值