C# Linq延遲查詢的執(zhí)行實(shí)例代碼
C# Linq延遲查詢
在定義linq查詢表達(dá)式時(shí),查詢是不會(huì)執(zhí)行,查詢會(huì)在迭代數(shù)據(jù)項(xiàng)時(shí)運(yùn)行。它使用yield return 語句返回謂詞為true的元素。
var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" }; var namesWithJ = from n in names where n.StartsWith("J") orderby n select n; Console.WriteLine("First iteration"); foreach (string name in namesWithJ) { Console.WriteLine(name); } Console.WriteLine(); names.Add("John"); names.Add("Jim"); names.Add("Jack"); names.Add("Denny"); Console.WriteLine("Second iteration"); foreach (string name in namesWithJ) { Console.WriteLine(name); }
運(yùn)行結(jié)果為
First iteration
JuanSecond iteration
Jack
Jim
John
Juan
從執(zhí)行結(jié)果可以看出,當(dāng)在定義namesWithJ時(shí)并不會(huì)執(zhí)行,而是在執(zhí)行每個(gè)foreach語句時(shí)進(jìn)行,所以后面增加的“John”、“Jim”、“Jack”和“Denny”在第二次迭代時(shí)也會(huì)參與進(jìn)來。
ToArray()、ToList()等方法可以改變這個(gè)操作,把namesWithJ的定義語句修改為
var namesWithJ = (from n in names where n.StartsWith("J") orderby n select n).ToList();
運(yùn)行結(jié)果為
First iteration
JuanSecond iteration
Juan
在日常工作中,我們常會(huì)使用 datas.Where(x=>x.XX == XXX).FirstOrDefault() 和 datas.FirstOrDefault(x=>x.XX == XXX),其實(shí)這兩種寫法性能是等效的,如果真的要在性能上分個(gè)高低,請見下面
C# Linq.FirstOrDefault、Linq.Where、Linq.AsParallel、List.Exists、List.Find、Dictionar.TryGetValue、HashSet.Contains 性能的比較
今天我們來比較一下集合檢索方法性能更優(yōu)問題,測試代碼
public class Entity { public int Id { get; set; } public int No { get; set; } public string Col1 { get; set; } public string Col2 { get; set; } public string Col3 { get; set; } public string Col4 { get; set; } public string Col5 { get; set; } public string Col6 { get; set; } public string Col7 { get; set; } public string Col8 { get; set; } public string Col9 { get; set; } public string Col10 { get; set; } } static void TestFindVelocity(int totalDataCount, int executeCount) { #region 構(gòu)造數(shù)據(jù) List<Entity> datas = new List<Entity>(); for (int i = 0; i < totalDataCount; i++) { var item = new Entity { No = i + 1, Col1 = Guid.NewGuid().ToString("N"), Col2 = Guid.NewGuid().ToString("N"), Col3 = Guid.NewGuid().ToString("N"), Col4 = Guid.NewGuid().ToString("N"), Col5 = Guid.NewGuid().ToString("N"), Col6 = Guid.NewGuid().ToString("N"), Col7 = Guid.NewGuid().ToString("N"), Col8 = Guid.NewGuid().ToString("N"), Col9 = Guid.NewGuid().ToString("N"), Col10 = Guid.NewGuid().ToString("N"), }; datas.Add(item); } #endregion var dicDatas = datas.ToDictionary(x => x.No); var hashSetDatas = datas.ConvertAll<Tuple<int, int>>(x => new Tuple<int, int>(x.No, x.No + 1000)).ToHashSet(); Stopwatch sw = new Stopwatch(); Random random = new Random(); Entity searchResult = null; bool searchResultBool = false; // 每次查詢索引 List<int> indexs = Enumerable.Range(1, executeCount).Select(x => random.Next(1, totalDataCount)).ToList(); sw.Start(); for (int i = 0; i < executeCount; i++) { searchResult = datas.FirstOrDefault(x => x.No == indexs[i]); } sw.Stop(); Console.WriteLine($"list FirstOrDefault 耗時(shí):{sw.ElapsedMilliseconds}"); sw.Restart(); for (int i = 0; i < executeCount; i++) { searchResult = datas.Where(x => x.No == indexs[i]).First(); } sw.Stop(); Console.WriteLine($"list Where+First 耗時(shí):{sw.ElapsedMilliseconds}"); sw.Restart(); for (int i = 0; i < executeCount; i++) { searchResultBool = datas.Exists(x => x.No == indexs[i]); } sw.Stop(); Console.WriteLine($"list Exist 耗時(shí):{sw.ElapsedMilliseconds}"); sw.Restart(); for (int i = 0; i < executeCount; i++) { searchResult = datas.Find(x => x.No == indexs[i]); } sw.Stop(); Console.WriteLine($"list Find 耗時(shí):{sw.ElapsedMilliseconds}"); sw.Restart(); for (int i = 0; i < executeCount; i++) { dicDatas.TryGetValue(indexs[i], out searchResult); } sw.Stop(); Console.WriteLine($"dictionary TryGetValue 耗時(shí):{sw.ElapsedMilliseconds}"); sw.Restart(); for (int i = 0; i < executeCount; i++) { searchResultBool = hashSetDatas.Contains(new Tuple<int, int>(indexs[i], indexs[i] + 1000)); } sw.Stop(); Console.WriteLine($"Hashset contains 耗時(shí):{sw.ElapsedMilliseconds}"); }
結(jié)果
(集合數(shù)量,測試次數(shù)) | Linq.FirstOrDefault | Linq.Where+First | List.Exists | List.Find | Dictionary.TryGetValue | HashSet.Contains |
(100, 5000000) |
4544 | 3521 | 1992 | 1872 | 66 | 924 |
(1000, 5000000) |
41751 | 29417 | 20631 | 19490 | 70 | 869 |
(10000, 5000000) |
466918 | 397425 | 276409 | 281647 | 85 | 946 |
(50000, 5000) |
6292 | 4602 | 4252 | 3559 | 0 | 2 |
(500000, 5000) |
56988 | 55568 | 48423 | 48395 | 1 | 5 |
應(yīng)避免錯(cuò)誤寫法是 datas.Where(x=>x.XX == XXX).ToList()[0]
。
總結(jié)
到此這篇關(guān)于C# Linq延遲查詢的執(zhí)行的文章就介紹到這了,更多相關(guān)C# Linq延遲查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C#集合查詢Linq在項(xiàng)目中使用詳解
- c# Linq查詢詳解
- c# 動(dòng)態(tài)構(gòu)建LINQ查詢表達(dá)式
- C#使用LINQ查詢表達(dá)式的基本子句總結(jié)
- C# linq查詢之動(dòng)態(tài)OrderBy用法實(shí)例
- C#中Linq延遲查詢的例子
- C#使用linq語句查詢數(shù)組中以特定字符開頭元素的方法
- C#使用linq查詢大數(shù)據(jù)集的方法
- C#中Linq查詢基本操作使用實(shí)例
- C# LINQ查詢表達(dá)式及對應(yīng)LAMBDA表達(dá)式的用法
- C#使用LINQ查詢操作符實(shí)例代碼(一)
相關(guān)文章
C#面向?qū)ο笾M實(shí)現(xiàn)商城購物功能
這篇文章主要為大家詳細(xì)介紹了C#面向?qū)ο笾M實(shí)現(xiàn)商城購物功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02利用C#自定義一個(gè)時(shí)間類型YearMonth
.Net6中加入了兩個(gè)新的時(shí)間類型:DateOnly和TimeOnly,但DateOnly和TimeOnly都有相應(yīng)的應(yīng)用場景,所以本文就來自定義一個(gè)時(shí)間類型YearMonth,用于解決實(shí)際項(xiàng)目開發(fā)中的需求,希望對大家有所幫助2023-07-07Unity實(shí)現(xiàn)主角移動(dòng)與攝像機(jī)跟隨
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)主角移動(dòng)與攝像機(jī)跟隨,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03unity 如何獲取Text組件里text內(nèi)容的長度
這篇文章主要介紹了unity 獲取Text組件里text內(nèi)容的長度操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04C#判斷一個(gè)字符串是否包含另一個(gè)字符串的方法
這篇文章主要介紹了C#判斷一個(gè)字符串是否包含另一個(gè)字符串的方法,涉及C#中IndexOf方法的使用技巧,非常簡單實(shí)用,需要的朋友可以參考下2015-04-04C#基礎(chǔ)語法:Base關(guān)鍵字學(xué)習(xí)筆記
這篇文章主要介紹了C#基礎(chǔ)語法:Base關(guān)鍵字學(xué)習(xí)筆記,本文講解了它的一些基礎(chǔ)知識(shí)以及測試代碼,需要的朋友可以參考下2015-06-06