首页 新闻 会员 周边 捐助

foreach 循环有100w数据非常慢,有什么优化的吗

0
悬赏园豆:20 [已解决问题] 解决于 2025-06-04 17:22

主要代码逻辑是这2段,第一段的foreach循环求出来的result 有100w 数据,然后非常慢,请问有什么优化的吗? 这是1年的数据,业务方就是要这样查,我现在的问题就是怎么处理foreach 这段逻辑,并行计算不给用

net
赚1千万就收手的主页 赚1千万就收手 | 小虾三级 | 园豆:1526
提问于:2025-06-04 10:08

我把这里注释了非常快

赚1千万就收手 2个月前
< >
分享
最佳答案
0

建议采用分页思路,比如一次 foreach 处理 1000 条,然后合并结果

收获园豆:10
dudu | 高人七级 |园豆:25263 | 2025-06-04 10:12

还可以考虑采用 Parallel.ForEach,参考 C#并发实战Parallel.ForEach使用

dudu | 园豆:25263 (高人七级) | 2025-06-04 10:14

上次是这样的,但是也很慢,头一个foreach 用了十几分钟 /哭

赚1千万就收手 | 园豆:1526 (小虾三级) | 2025-06-04 10:15

@赚1千万就收手: 电脑的CPU或内存有没有跑满?

dudu | 园豆:25263 (高人七级) | 2025-06-04 10:24

@赚1千万就收手: 可以试试 Span 的威力

var asSpanList = CollectionsMarshal.AsSpan(result);
for (var i = 0; i < asSpanList.Length; i++)
{
    var item = asSpanList[i];
}
dudu | 园豆:25263 (高人七级) | 2025-06-04 10:34

@赚1千万就收手: 还可以考虑使用 ref + Span

var asSpanList = CollectionsMarshal.AsSpan(result);
ref BillPaymentStatisticsResponse ptr = ref MemoryMarshal.GetReference(asSpanList);
for (var i = 0; i < asSpanList.Length; i++)
{
    var item = Unsafe.Add(ref ptr, i);
}
dudu | 园豆:25263 (高人七级) | 2025-06-04 10:44

@赚1千万就收手: 找到一篇很好的参考博文:C# Array and List Fastest Loop in 2025

dudu | 园豆:25263 (高人七级) | 2025-06-04 10:46

@dudu: 不给用这个了,原来用过

赚1千万就收手 | 园豆:1526 (小虾三级) | 2025-06-04 11:44
其他回答(3)
0

item.sum 这种代码可以转为手动写. 每一次的.sum都要遍历一次. 累计的循环次数100w* 20 (大概数了一下), 改一下就提高20倍性能了.

sum_usd, sum_cny
for i in item
  if(...) sum_usd+= i.usd
  if(...) sum_cny+= i.cny

然后几个list也可以初始化的时候给好容量 response = new List<T>(result.count) 类似于.
在然后, _groupByFeeType 可以并发执行. _response = _groupByFeeType.AsParallel().Select(item=>{sum_usd, sum_cny的逻辑})

收获园豆:10
czd890 | 园豆:14650 (专家六级) | 2025-06-04 12:23


我看 foreach 20w 的数据,这里非常慢, 几分钟才 response.Add 了1w多条数据

支持(0) 反对(0) 赚1千万就收手 | 园豆:1526 (小虾三级) | 2025-06-04 17:06


我把这里注释了非常快

支持(0) 反对(0) 赚1千万就收手 | 园豆:1526 (小虾三级) | 2025-06-04 17:13

@赚1千万就收手:
慢在了 user.Where 上把, 大概? 这是到数据库查去了?

支持(0) 反对(0) czd890 | 园豆:14650 (专家六级) | 2025-06-04 17:27

@czd890: 不是,已经从数据库查出来了
= string.Join(",", getCompanyList.Where(x => x.Id == item.BelongCompanyId).Select(x => x.NameCn)); 这个慢

支持(0) 反对(0) 赚1千万就收手 | 园豆:1526 (小虾三级) | 2025-06-04 17:36
0

先降低负责度O(n)降到O(1): 类似:// Create this once when you load the data
var companyDictionary = getCompanyList.ToDictionary(x => x.Id, x => x.NameCn);

pccai | 园豆:209 (菜鸟二级) | 2025-06-06 16:33
0

不是慢在循环上了。是慢在条件查询和聚合上了。一次查找就遍历100w,
换成字典,提前聚合,下面的直接key查找结果,性能直接就上来了。

w0rd | 园豆:526 (小虾三级) | 2025-07-12 11:35
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册