今晚遇到一个很奇怪的事情,我已经把所有数据拿出来了,然后在后台用C#代码根据业务对数据进行处理,大抵都是用linq进行一些where、any、select的处理,中间还夹杂着两三个foreach,结果当数据稍微多一点,直接卡死!
一步步地把觉得可能会耗性能的操作都注释,最后发现一个只有一条数据的Enumerable变量,在做.Any()判断时,都耗时0.5秒左右!顿时崩溃……最后把所有需要处理的数据ToList一下,OK,收工!
没有写ToList操作,是因为前阵子看了网上有人说ToList耗性能,So……不过想了想,其实是自己理解不到位呀。在不需要对Where出来的数据进行操作时,直接使用Enumerable,提高性能是有道理的。但需要对Enumerable数据进行更多的处理时,是不是因为变量引用的关系,后续的数据操作还是引用到原始的数据源上,从而导致性能下降呢?这只是我个人的想法,接下来需要好好研究下~~~
顺便附上MSDN里的相关资料:Enumerable.ToList<TSource> 方法
最后贴上一些代码,在作为备忘时,希望大家指点代码中需要优化的地方:)
subPickSampleList、bottleList、mainList等都是List数据源。最后是往一个DataTable里添加Row数据。
1 var subPickSampleList = pickSampleList.Where(i => boilerGasType == null || (i.PickID.ToString() != boilerGasType.PickId)).OrderBy(i => i.MonitorSitePlace).ToList(); 2 var myBottleList = bottleList.Where(b => subPickSampleList.Select(ps => ps.MonitorSampleID).Contains(b.MonitorSampleID)).ToList(); 3 var bottleMainList = mainList.Where(i => i.BottleID != null).ToList(); 4 6 foreach (var sample in subPickSampleList) 7 { 8 var siteBottle = myBottleList.Where(i => i.MonitorSampleID == sample.MonitorSampleID).ToList(); 9 var siteBottleId = siteBottle.Select(b => b.BottleID).ToList(); 10 var myMain = bottleMainList.Where(i => siteBottleId.Contains(i.BottleID.Value)).ToList(); 11 12 if (!myMain.Any()) 13 { 14 continue; 15 } 16 var newContentRow = contentTable.NewRow(); 17 18 #region initialize a NewRow 19 20 newContentRow["PickDate"] = sample.PickTime == null ? "-" : sample.PickTime.Value.ToString("MM/dd"); 21 newContentRow["SecondCode"] = siteBottle.First().SecondCode; 22 newContentRow["SitePlace"] = sample.MonitorSitePlace; 23 24 foreach (var item in otherItemList) 25 { 26 foreach (var main in myMain) 27 { 28 if (main.Item == item) 29 { 30 var result = resultList.First(i => i.MainSampleID == main.MainSampleID); 31 newContentRow[item] = result.RoundValue; 32 break; 33 } 34 } 35 } 36 37 #endregion 38 39 contentTable.Rows.Add(newContentRow); 40 41 }