zoukankan      html  css  js  c++  java
  • 【转】编写高质量代码改善C#程序的157个建议——建议84:使用PLINQ

    建议84:使用PLINQ

    LINQ最基本的功能就是对集合进行遍历查询,并在此基础上对元素进行操作。仔细推敲会发现,并行编程简直就是专门为这一类应用准备的。因此,微软专门为LINQ拓展了一个类ParallelEnumerable(该类型也在命名空间System.Linq中),它所提供的扩展方法会让LINQ支持并行计算,这就是所谓的PLINQ。

    传统的LINQ计算是单线程的,PLINQ则是并发的、多线程的,我们通过下面这个示例就可以看出这个区别:

    static void Main(string[] args)  
    {  
        List<int> intList = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };  
        var query = from p in intList select p;  
        Console.WriteLine("以下是LINQ顺序输出:");  
        foreach (int item in query)  
        {  
            Console.WriteLine(item.ToString());  
        }  
        Console.WriteLine("以下是PLINQ并行输出:");  
        var queryParallel = from p in intList.AsParallel() select p;  
        foreach (int item in queryParallel)  
        {  
            Console.WriteLine(item.ToString());  
        }  
    } 

    LINQ的输出会按照intList中的索引顺序打印出来。而PLINQ的输出是杂乱无章的。

    并行输出还有另外一种方式可以处理,那就是对queryParallel求ForAll:

    queryParallel.ForAll((item) =>
    {  
        Console.WriteLine(item.ToString());  
    }); 

    但是这种方法会带来一个问题,如果要将并行输出后的结果进行排序,ForAll会忽略掉查询的AsOrdered请求。如下所示:

    var queryParallel = from p in intList.AsParallel().AsOrdered() select p;  
    queryParallel.ForAll((item) =>
    {  
        Console.WriteLine(item.ToString());  
    }); 

    AsOrdered方法可以对并行计算后的队列进行重新组合,以便保持顺序。可是在ForAll方法中,它所完成的输出仍是无序的。如果要保持AsOrdered方法的需求,我们应当始终使用第一种并行方式,即:

    var queryParallel = from p in intList.AsParallel().AsOrdered() select p;  
    foreach (int item in queryParallel)  
    {  
        Console.WriteLine(item.ToString());  
    } 

    在并行查询后再进行排序,会牺牲掉一定的性能。一些扩展方法默认会对元素进行排序,这些方法包括:OrderBy、OrderByDescending、ThenBy和ThenByDescending。在实际的使用中,一定要注意到各种方式之间的差别,以便程序按照我们的设想运行。

    还有一些其他的查询方法,比如Take。如果我们这样编码:

    foreach (int item in queryParallel.Take(5))  
    {  
        Console.WriteLine(item.ToString());  
    }
    在顺序查询中,会返回前5个元素。但是在PLINQ中,会选出5个无序的元素。

    建议在对集合中的元素项进行操作的时候使用PLINQ代替LINQ。但是要记住,不是所有并行查询的速度都会比顺序查询快,在对集合执行某些方法时,顺序查询的速度会更快一点,如方法ElementAt等。在开发中,我们应该仔细辨别这方面的需求,以便找到最佳的解决方案。

    转自:《编写高质量代码改善C#程序的157个建议》陆敏技

  • 相关阅读:
    [computer graphics]世界坐标系->相机坐标系详细推导
    [Computer Vision]霍夫变换直线检测
    [OpenGL](翻译+补充)投影矩阵的推导
    [WebGL]二维变换
    [WebGL]Shader中的数据和简单的工作流
    图像梯度
    皮肤镜图片毛发去除
    胸部CT提取分割肺部
    医学影像重采样
    ES7学习笔记(十二)高亮 和 搜索建议
  • 原文地址:https://www.cnblogs.com/farmer-y/p/7993858.html
Copyright © 2011-2022 走看看