以下測試結果有誤!!!
linq為延遲執行語句,調用結果時,才執行查詢語句。
留文自省!!
.Net 3.5之后出現了linq,它包含幾個分類:LINQ to Object, LINQ to XML, LINQ to SQL, LINQ to DataSet,LINQ to ADO.NET。本篇說說linq to object的部分用法的性能測試。
首先,用linq實現修改集合中的每個元素。
List<string> xxx = new List<string>() { "aaaa", "bbbb", "aaabbb", "cccc", "aaaccc" }; var linq = xxx.Select(x => "000" + x);
值得注意的是,Select返回的類型是IEnumerable的,可就是可枚舉類型。它的優勢在於多個linq語句一起執行時,只會歷遍一次(盡量少的次數)來獲取結果。
如果上面的這段代碼用基本的c#語句來實現,代碼應該如下:
var yyy = new List<string>(); foreach (var item in xxx) yyy.Add("000" + item);
下面通過代碼來同時測試兩者的性能。
List<string> xxx = new List<string>() { "aaaa", "bbbb", "aaabbb", "cccc", "aaaccc" }; System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); System.Diagnostics.Stopwatch watch2 = new System.Diagnostics.Stopwatch(); System.Diagnostics.Stopwatch watch3 = new System.Diagnostics.Stopwatch(); watch.Start(); for (int i = 0; i < 100000; i++) { var linq = xxx.Select(x => "000" + x);//Linq,返回IEnumerable } watch.Stop(); var useTime = (double)watch.ElapsedMilliseconds; watch2.Start(); for (int i = 0; i < 100000; i++) { var linq = xxx.Select(x => "000" + x).ToList();//Linq + ToList,返回List } watch2.Stop(); var useTime2 = (double)watch2.ElapsedMilliseconds; watch3.Start(); for (int i = 0; i < 100000; i++) { var yyy = new List<string>(); foreach (var item in xxx) yyy.Add("000" + item);//foreach,返回List } watch3.Stop(); var useTime3 = (double)watch3.ElapsedMilliseconds;
用十萬次的循環來測試消耗的時間。測試對象包括:
純Linq語句的修改,返回IEnumerable<string>;Linq語句修改 + ToList(),最后返回List<string>;foreach歷遍修改,返回List<string>。執行這段代碼,查看useTime的結果。運行一次的結果如下:
useTime = 11.0
useTime2 = 87.0
useTime3 = 73.0
由這個結果可以得出:Linq修改的速度最快,其次是foreach歷遍,linq+ToList最慢。在平時的使用過程中,如果返回的結果不是必須轉換成List集合的情況下,用Linq可以更快更節省代碼!不熟悉IEnumerable接口的可以深入了解一下,它是可枚舉類型,可以用foreach來歷遍,List和Array都繼承了這個接口。
linq的另一個很明顯的優勢是,它可以多個函數命令累積執行。形如Linq.Select().Where().GroupBy().Select();這樣的代碼無疑更精簡。以下同樣通過代碼來測試這樣的linq效率如何。
實現的目標:在修改的同時查詢過濾,同時用linq和foreach歷遍實現。
List<string> xxx = new List<string>() { "aaaa", "bbbb", "aaabbb", "cccc", "aaaccc" }; System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); for (int i = 0; i < 100000; i++) { var linq = xxx.Select(x => "000" + x).Where(x => x.IndexOf("aaa") != -1).ToList(); } watch.Stop(); var useTime = (double)watch.ElapsedMilliseconds; System.Diagnostics.Stopwatch watch2 = new System.Diagnostics.Stopwatch(); watch2.Start(); for (int i = 0; i < 100000; i++) { var yyy = new List<string>(); foreach (var item in xxx) { var tmp = "000" + item; if (tmp.IndexOf("aaa") != -1) yyy.Add(tmp); } } watch2.Stop(); var useTime2 = (double)watch2.ElapsedMilliseconds;
執行的結果:useTime = 18.0; useTime2 = 379.0 效率差距出來了。
在只有單個命令的前提下,linq和foreach執行的效率相差只有幾倍,多個命令時,linq的效率就明顯比foreach快很多了。
補充:在linq語句的后面加上ToList()來執行linq語句。最終結果:useTime = 404.0; useTime2 = 333.0.
補充測試:select+groupby+select VS foreach
List<KeyValuePair<string, string>> xxx = new List<KeyValuePair<string, string>>() { new KeyValuePair<string,string>("a", "b"), new KeyValuePair<string,string>("a", "c"), new KeyValuePair<string,string>("a", "d"), new KeyValuePair<string,string>("a", "e"), new KeyValuePair<string,string>("b", "a"), new KeyValuePair<string,string>("b", "b"), new KeyValuePair<string,string>("b", "c") }; System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); List<string> res = new List<string>(); for (int i = 0; i < 100000; i++) { res.Clear(); var linq = xxx.Select(x => new { x.Key, Value = "000" + x.Value }) .GroupBy(x => x.Key) .Select(x => x.Key + ":" + x.Select(y => y.Value).Aggregate((y, z) => y + "_" + z)); res.AddRange(linq); } watch.Stop(); var useTime = (double)watch.ElapsedMilliseconds; System.Diagnostics.Stopwatch watch2 = new System.Diagnostics.Stopwatch(); watch2.Start(); for (int i = 0; i < 100000; i++) { res.Clear(); var dic = new Dictionary<string, string>(); foreach (var x in xxx) { var tmp = "_" + "000" + x.Value; if (!dic.ContainsKey(x.Key)) dic.Add(x.Key, tmp); else dic[x.Key] += tmp; } foreach (var x in dic) res.Add(x.Key + ":" + (string.IsNullOrWhiteSpace(x.Value) ? "" : x.Value.Remove(0, 1))); } watch2.Stop(); var useTime2 = (double)watch2.ElapsedMilliseconds;
調試得到結果:useTime = 422.0; useTime2 = 228.0。結合上面的調試結果,linq的執行效率基本上都要比用基礎代碼編寫的foreach要慢一點。
轉載請注明出處:http://www.cnblogs.com/icyJ/
補充二:其他人的說法。沒有測試過。AsParallel()這個方法值得深究。
“要真正比較linq的好處,不能用這么簡單的代碼的。你嘗試一下
int[] result=list.AsParallel().Where(i=>i%3==0).Select(i=>i*i).ToArray();
然后用for循環和lambda同樣實現一個多線程的求解,你就知道linq的威力了。
一般來說,如果你自己調度的不好,性能肯定比linq差。但是如果你調度的好,你會發現“我寫了這么多代碼,只比linq快了那么一點點,但是linq只有一行”,所以最終你會選擇linq。”
