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

发布时间:2024年01月19日
简介

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进行测试。

文章来源:https://blog.csdn.net/yunxiaobaobei/article/details/135694496
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。