建议84:使用PLINQ

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

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

static void Main(string[] args)
{
List<int> intList = new List<int>() { , , , , , , , , , };
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个建议》陆敏技

最新文章

  1. Linq语法详细
  2. ThinkPHP 3.2.3 文件上传时间目录问题
  3. blog搬迁
  4. linux下使用 Tomcat 的几个坑
  5. Codeforces Round #Pi (Div. 2) C. Geometric Progression map
  6. ArcGIS API for Silverlight 之ElementLayer使用及TextSymbol的模板使用
  7. xcode使用
  8. C# mvc--EF中查询的本质
  9. 实例介绍Cocos2d-x中Box2D物理引擎:碰撞检测
  10. c# 类型初始值设定项引发异常
  11. Struts数据效验
  12. JavaEE JavaBean 反射、内省、BeanUtils
  13. PHP 正则小解
  14. MP3 信息读取
  15. python开发部署时新增数据库中表的方法
  16. python 线程/线程锁/信号量
  17. (4)Python列表list
  18. [APIO2013]机器人(斯坦纳树)
  19. 吴恩达机器学习CS229课程笔记学习
  20. 7.26-STOIRegularMatch-08-#14

热门文章

  1. 论 html与css的关系
  2. apk比较版本大小
  3. TypeError: &#39;ExcelData&#39; object is not iterable
  4. Mysql总结(二)
  5. Python网络编程与并发编程
  6. canvas的性能优化
  7. npm安装elasticsearch-reindex
  8. 【2018沈阳赛区网络预选赛J题】Fantastic Graph 【有上下界的网络流】
  9. Gym101128G:Game of Cards
  10. 高性能Web服务器Nginx的配置与部署研究(12)应用模块之Memcached做文件缓存时压缩引起的问题