当前位置: 首页 > news >正文

关于C#中的LINQ的延迟执行

简介

Linq中的绝大多数查询运算符都有延迟执行的特性,查询并不是在查询创建的时候执行,而是在遍历的时候执行

实例:

 public void Test2(){List<int> items = new List<int>() { -1, 1, 3, 5 };IEnumerable<int> items2 = items.Where(x => x > 0);foreach (int item in items2){Console.WriteLine(item);}items.Add(40);Console.WriteLine("----------------");foreach (int item in items2){Console.WriteLine(item);}Console.WriteLine("*****************");}

运行结果:

可以看到,执行结果也验证上述的说明,查询创建后,并没有马上执行,而是在遍历对象时才执行,否则第二个遍历不会打印出40.

如果在查询后面添加ToList等转换符,则会立即执行,如

IEnumerable<int> items2 = items.Where(x => x > 0).ToList();

扩展1

上面我们使用时LINQ的API语法,还有一种时查询语法,上面的语句可以改写为:

IEnumerable<int> items3 = from n in itemswhere n > 0select n;foreach (int item in items3)
{Console.WriteLine(item);
}

两种方案区别不大。唯一的区别查询语法允许使用 let 子句,这样,便可以在表达式的作用域内引入和绑定变量,然后在表达式的后续片段中使用该变量。 只使用 API 语法重现相同的代码也是可行的,不过,这很可能会导致代码难以阅读。

扩展2

PLINQ(又称并行 LINQ)是 LINQ 表达式的并行执行引擎。 换言之,LINQ 正则表达式可能会没有意义地在任意数量的线程之间并行化。 为此,可以调用表达式前面的 AsParallel()

上面的代码可以做一下扩展使用并行库执行

IEnumerable<int> items2 = items.AsParallel().Where(x => x > 0);

实例:

  Stopwatch stopwatch = new Stopwatch();public  void TestPLINQ(){stopwatch.Restart();IEnumerable<int> numbers = Enumerable.Range(3, 10000000 - 3);var parallelQuery =from n in numbers.AsParallel()where Enumerable.Range(2, (int)Math.Sqrt(n)).All(i => n % i > 0)select n;int[] primes = parallelQuery.ToArray();Console.WriteLine("PLINQ 耗时:" + stopwatch.ElapsedMilliseconds.ToString() + "ms");stopwatch.Stop();}public  void TestLINQ(){stopwatch.Restart();IEnumerable<int> numbers = Enumerable.Range(3, 10000000 - 3);var parallelQuery =from n in numbers//AsParallel()where Enumerable.Range(2, (int)Math.Sqrt(n)).All(i => n % i > 0)select n;int[] primes = parallelQuery.ToArray();Console.WriteLine("LINQ 耗时:" + stopwatch.ElapsedMilliseconds.ToString() + "ms");stopwatch.Stop();}

执行结果:

可以看到,对于CPU密集型任务,使用PLINQ执行的效率有明显提升。

注意1:针对单核CPU来说没有意义。
注意2:对于耗时时间很短的情况,可能LINQ的执行效率会比PLINQ要快,所有使用时要具体情况具体分析。可以将上述的数组大小修改为10000进行测试。

相关文章:

  • 计算机网络复试
  • ASEPRITE使用笔记
  • Redis(六)发布订阅,不推荐
  • 【JavaWeb后端开发-第八章】Maven高级
  • 如何在 Ubuntu 22.04 上安装 Apache Web 服务器
  • 立体视觉几何 (二)
  • 【第七在线】智能商品计划:让供应链管理更加智能、高效
  • 综述:自动驾驶中的 4D 毫米波雷达
  • 数据结构:堆与堆排序
  • go和swoole性能比较
  • 低代码技术杂谈
  • QT基础篇(10)QT5网络与通信
  • Git--基本操作介绍(2)
  • 在react中说说对受控组件和非受控组件的理解?以及应用场景
  • Android状态栏布局隐藏的方法
  • angular组件开发
  • const let
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • JavaScript的使用你知道几种?(上)
  • PHP面试之三:MySQL数据库
  • Spark RDD学习: aggregate函数
  • TCP拥塞控制
  • vue-loader 源码解析系列之 selector
  • 笨办法学C 练习34:动态数组
  • 分享一份非常强势的Android面试题
  • 浮动相关
  • 警报:线上事故之CountDownLatch的威力
  • 来,膜拜下android roadmap,强大的执行力
  • 面试总结JavaScript篇
  • 爬虫模拟登陆 SegmentFault
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 写代码的正确姿势
  • k8s使用glusterfs实现动态持久化存储
  • RDS-Mysql 物理备份恢复到本地数据库上
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • 从如何停掉 Promise 链说起
  • ​比特币大跌的 2 个原因
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • (06)金属布线——为半导体注入生命的连接
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (poj1.2.1)1970(筛选法模拟)
  • (附源码)ssm码农论坛 毕业设计 231126
  • (利用IDEA+Maven)定制属于自己的jar包
  • (十) 初识 Docker file
  • (十八)三元表达式和列表解析
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (图)IntelliTrace Tools 跟踪云端程序
  • (五)c52学习之旅-静态数码管
  • . NET自动找可写目录
  • .NET BackgroundWorker