C#遍历超大List的foreach性能极差,求优化方案
C# 大规模列表遍历的性能优化问题
我有一个遍历response的foreach循环,response是最多包含23万条记录的List。每次遍历response时,会过滤并求和另一个最多3万条记录的_MaterialIssued列表;仅当Issued>0时(约15%的情况)才进入后续分支。接着从最多1.7万条记录的_OnHand列表中获取itemOnhand,约85%的情况会进入该分支,而此分支内的代码导致性能急剧下降——需要再次过滤response获取子项并修改_OnHand和response列表。
该foreach循环的执行时间因机器而异,耗时45至75分钟,我无法定位瓶颈所在,也不知道如何优化此代码块。我曾尝试将_OnHand列表改为HashSet,但性能无改善。
核心循环代码
foreach (var b in response) { var Issued = _MaterialIssued.Where(x => x.ItemId == b.ItemId && x.Job == b.Job).Sum(c => c.Qty); if (Issued > 0) { var prctIssued = Issued / b.QtyDemand; var childItems = response.Where(x => x.Job == b.Job && x.BomPath.StartsWith(b.BomPath)); foreach (var child in childItems) { child.QtyIssued = child.QtyDemand * prctIssued; } } var itemOnhand = _OnHand.Where(x => x.ItemId == b.ItemId).FirstOrDefault(); if (itemOnhand.Onhand > 0) { decimal prctOnhand = 1; var childItems = response.Where(x => x.Job == b.Job && x.BomPath.StartsWith(b.BomPath) && x.ItemId != b.ItemId && x.SiteRef == b.SiteRef && x.QtyIssued < x.QtyDemand); var DemandWithIssued = b.QtyDemand - b.QtyIssued; if (itemOnhand.Onhand < DemandWithIssued) { prctOnhand = itemOnhand.Onhand / DemandWithIssued; } itemOnhand.Onhand -= DemandWithIssued * prctOnhand; foreach (var child in childItems) { child.QtyParentAvailable = (child.QtyDemand - child.QtyIssued) * prctOnhand; } } }
相关模型定义
_OnHand 模型
private class ItemOnhand { public string ItemId { get; set; } public string SiteRef { get; set; } public decimal Onhand { get; set; } }
_MaterialIssued 模型
public class FiniteDemandBase { public string ItemId { get; set; } public string Item { get; set; } public string JobId { get; set; } public string Job { get; set; } public DateTime StartDate { get; set; } public string SiteRef { get; set; } public decimal Qty { get; set; } }
response 模型
public class FiniteDemand { public int Id { get; set; } public DateTime StartDate { get; set; } public string BomPath { get; set; } public string SiteRef { get; set; } public string Job { get; set; } public string ItemId { get; set; } public string JobId { get; set; } public string ParentItemId { get; set; } public decimal QtyPerUnit { get; set; } public decimal QtyDemand { get; set; } public decimal QtyOnhand { get; set; } public decimal QtyWip { get; set; } public decimal QtyOnhandRunning { get; set; } public decimal QtyInSchedule { get; set; } public decimal QtyIssued { get; set; } public decimal QtyParentAvailable { get; set; } public decimal QtyDemandNeeded { get; set; } public decimal QtyDemandNeededRunning { get; set; } }
内容的提问来源于stack exchange,提问作者Abraham Friessen
相关产品推荐
相关产品推荐

