C# Linq延迟查询 C# Linq延迟查询的执行实例代码
沉默♪☞小傲 人气:0想了解C# Linq延迟查询的执行实例代码的相关内容吗,沉默♪☞小傲在本文为您仔细讲解C# Linq延迟查询的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:c#,linq延迟查询,下面大家一起来学习吧。
C# Linq延迟查询
在定义linq查询表达式时,查询是不会执行,查询会在迭代数据项时运行。它使用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); }
运行结果为
First iteration
JuanSecond iteration
Jack
Jim
John
Juan
从执行结果可以看出,当在定义namesWithJ时并不会执行,而是在执行每个foreach语句时进行,所以后面增加的“John”、“Jim”、“Jack”和“Denny”在第二次迭代时也会参与进来。
ToArray()、ToList()等方法可以改变这个操作,把namesWithJ的定义语句修改为
var namesWithJ = (from n in names where n.StartsWith("J") orderby n select n).ToList();
运行结果为
First iteration
JuanSecond iteration
Juan
在日常工作中,我们常会使用 datas.Where(x=>x.XX == XXX).FirstOrDefault() 和 datas.FirstOrDefault(x=>x.XX == XXX),其实这两种写法性能是等效的,如果真的要在性能上分个高低,请见下面
C# Linq.FirstOrDefault、Linq.Where、Linq.AsParallel、List.Exists、List.Find、Dictionar.TryGetValue、HashSet.Contains 性能的比较
今天我们来比较一下集合检索方法性能更优问题,测试代码
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 构造数据 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 耗时:{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 耗时:{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 耗时:{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 耗时:{sw.ElapsedMilliseconds}"); sw.Restart(); for (int i = 0; i < executeCount; i++) { dicDatas.TryGetValue(indexs[i], out searchResult); } sw.Stop(); Console.WriteLine($"dictionary TryGetValue 耗时:{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 耗时:{sw.ElapsedMilliseconds}"); }
结果
(集合数量,测试次数) | 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 |
应避免错误写法是 datas.Where(x=>x.XX == XXX).ToList()[0]
。
总结
加载全部内容