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

23 篇文章 0 订阅
18 篇文章 0 订阅
简介

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 items
            where n > 0
            select 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进行测试。

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

破浪征程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值