C# Linq延迟查询的执行实例代码
作者:沉默♪☞小傲 发布时间:2023-04-24 05:34:59
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]
。
来源:https://www.cnblogs.com/Cxiaoao/p/14674744.html


猜你喜欢
- Comparable 简介Comparable 是排序接口。若一个类实现了Comparable接口,就意味着“该类支持排序”。
- 在国际化环境下,越来越多的程序需要做多语言版本,以适应各种业务需求的变化。在Winform应用程序中实现多语言也有常规的处理方式处理,不过需
- 特简单, 没有数据库, 还没有处理各种异常。登录:输入用户名点击的登录即可。发送消息: 特定格式->toUser:message1.
- 最近开发遇到了个问题,app升级的时候,其他手机都能正常升级,下载完安装包,跳到安装页面进行新版本的安装。但却有用户反映,华为P10和华为M
- Android在布局文件中为View提供了onClick属性,使用方法如下:<TextView android:id=&
- 本文实例讲述了C#可用于登录验证码的四位随机数生成方法。分享给大家供大家参考。具体实现方法如下:这里提供了两种方法,调用其一即可:using
- 一直使用Eclipse环境开发Android,也尝鲜使用过Android Studio去开发,各种IDE配合Android SDK及SDK原
- 原理 Redis Cluster 一般由多个节点组成,节点数量至少为 6 个才能保证组成完整高可用的集群,其中三个为主
- 注:完整项目下载在处理了核心任务之后,我们会发现有些请求并不是都是静态的,那么我们就需要进行实现处理动态请求的要求,如下面代码是我们请求的解
- 我们知道,使用nginx作为文件下载服务器,可以极大地降低对后端Java服务器的负载冲击,但是nginx本身并不提供授权控制,因此好的方案是
- 一.类与接口的区别类:描述了一个实体,包括实体的状态,也包括实体可能发出的动作。接口:定义了一个实体可能发出的动作。但是只是定义了这些动作的
- Shiro介绍Shiro是一款安全框架,主要的三个类Subject、SecurityManager、RealmSubject:表示当前用户S
- 认证:验证当前访问系统的是不是本系统的用户,并且要确认具体是哪个用户授权:经过认证后判断当前用户是否有权限进行某个操作一、登录校验流程1、S
- 思维导图一、为什么要学习 DialogFragment你还在用 Dialog 吗?你还在经常烦恼于屏幕翻转的时候,Dialog 的各种奇葩情
- 一、Struts2 * 原理:Struts2 * 的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,
- 1.异步委托开启线程public class Program { public static void
- 一、回顾Stream管道流操作通过前面章节的学习,我们应该明白了Stream管道流的基本操作。我们来回顾一下:源操作:可以将数组、集合类、行
- 一)URL代理请求 该方式请求有两种代理方式。方式一:使用该方式代理之后,之后的所有接口都会使用代理请求// 对http开启全局代理Syst
- 本文介绍了ImageView 实现Android colorPikcer 选择器的示例代码,分享给大家,具体如下:Android color
- mapper.xml文件<?xml version="1.0" encoding="UTF-8"