今晚遇到一個很奇怪的事情,我已經把所有數據拿出來了,然后在后台用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 }