# LINQ 的一點優化,與 foreach、for 比較 ###### tags: `.Net` `LINQ` 有一天同仁撰寫了一段程式,但寫出來測試覺得執行時間過久。於是我們就一同探討 程式如下: ``` .net List<student> studentCollection = await client.GetDatabase("sample_training").GetCollection<student>("grades").AsQueryable().ToListAsync(); Dictionary<double, List<student>> studentDic = new Dictionary<double, List<student>>(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Restart(); stopWatch.Start(); List<double> studentIds = studentCollection.Select(s => s.student_id).Distinct().ToList(); studentIds.ForEach(item => { studentDic.Add(item, studentCollection.Where(f => f.student_id == item).ToList()); } stopWatch.Stop(); Console.WriteLine("First LINQ Version: " + stopWatch.Elapsed.TotalMilliseconds); ``` 這段程式本身看起來是沒有甚麼太大的問題,將不重複的 student_id 取出,並依序做事。 但假設這個集合本身是一個很巨量的時候,就會遇到執行不佳的問題(將資料筆數拉到30萬) 測試的數據如下:  從上面的圖片可以看出,兩者的差異是非常的巨大 於是就有一說是 LINQ 這一類 Lambda 語法的鍋,必須使用傳統的迴圈進行處理。 接著進行調整如下: ``` c# Dictionary<double, List<student>> studentsDic = new Dictionary<double, List<student>>(); foreach (var item in studentCollection) { if (studentsDic.ContainsKey(item.student_id)) { studentsDic[item.student_id].Add(item); } else { studentsDic.Add(item.student_id, new List<student>()); } } ``` 但覺得 LINQ 已經推出已久,應該是在使用上有一些誤用。 接著調整如下: ``` studentDic = studentCollection.GroupBy(x => x.student_id) .ToDictionary(x => x.Key, x => x.ToList()); ``` 針對 student_id 做 GroupBy 接著 ToDictionary。讓整個語法跟可讀性有很大的改進,不過 foreach、for 也有效能上的比較,下面也有使用 for 進行調整的寫法。 調整如下: ``` for (int i = 0; i < studentCollection.Count; i++) { var item = studentCollection[i]; if (studentDic.ContainsKey(item.student_id)) { studentDic[item.student_id].Add(item); } else { studentDic.Add(item.student_id, new List<student>()); } } ``` 整個最後測試的數據如下:  最後可以看出,LINQ 如果好好調整的話,效能是不會大幅輸 foreach、for
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up