擁有476550數據的一張數據表。使用其中的某個字段分組,然後按該字段進行排序。該需求分別使用LinQ to SQL和non-LinQ的方式實現,然後來看一下performance對比。
LinQ way
from p in context.Part_Part group p by p.FunctionGroup into groupedPs orderby groupedPs.Key select groupedPs LinQ way for group
non-LinQ way
var results = new SortedDictionary<long?, IList<Part_Part>>(); foreach (var p in context.Part_Part) { IList<Part_Part> groupedValue = null; if (!results.TryGetValue(p.FunctionGroup, out groupedValue)) { groupedValue = new List<Part_Part>(); results[p.FunctionGroup] = groupedValue; } groupedValue.Add(p); } non-LinQ way for group
從
var results = new SortedDictionary<long?, IList<Part_Part>>();
可以看出,用來排序的字段類型為long?。先看一下執行時間。
LinQ Way non-LinQ Way first time 1:6.698 6.707 second time 1:7.404 1.426 third time 1:7.127 1.486 forth time 1:6.952 1.425
明顯可以看出在這個scenario下,LinQ的performance極低。調整代碼,這次使用類型為string的PartDescription分組。測試,結果如下。
LinQ Way non-LinQ way first time >30min 8.738 second time >30min 4.201 third time >30min 4.173 forth time >30min 4.176
這個scenario下,non-LinQ way耗時有所增加,而LinQ way更是慘不忍睹。甚至在苦苦的等了30分鐘不見結果後,提早結束了測試程序。
可見,LinQ在帶來簡潔風和極佳可讀性的同時,也帶來了性能的損耗。看一段來自於《LinQ in Action》中,關於LinQ性能問題的描述。
There are no surprises. LINQ does not come for free. LINQ queries cause additional work, object creations, and pressure on the garbage collector. The additional cost of using LINQ can vary a lot depending on the query. It can be as low as 5 percent, but can sometimes be around 500 percent.
既如此,以後還能不能愉快的使用LinQ呢?再來看一段《LinQ in Action》中的描述。
Do not be afraid to use LINQ, but use it wisely. For simple operations that are executed extensively in your code, you may consider using the traditional alternatives. For simple filter or search operations, you can stick to the methods offered by List<T> and arrays, such as FindAll, ForEach, Find, ConvertAll, or TrueForAll. Of course, you can continue to use the classic for and foreach statements wherever LINQ would be overkill. For queries that are not executed several times per second, you can probably use LINQ to Objects safely. A query that is executed only once in a non-time-critical context won't make a big difference if it takes 60 milliseconds to execute instead of 10.