用于对内存中的数据做并行运算,也就是说其只支持 LINQ to Object 的并行运算

一、AsParallel(并行化)

就是在集合后加个AsParallel()。

例如:

var numbers = Enumerable.Range(, );
var result = numbers.AsParallel().AsOrdered().Where(i => i % == );
foreach (var i in result)
Console.WriteLine(i);

下面我们模拟给ConcurrentDictionary灌入1500w条记录,看看串行和并行效率上的差异,注意我的老爷机是2个硬件线程。

static void Main(string[] args)
{
var dic = LoadData(); Stopwatch watch = new Stopwatch(); watch.Start(); //串行执行
var query1 = (from n in dic.Values
where n.Age > && n.Age <
select n).ToList(); watch.Stop(); Console.WriteLine("串行计算耗费时间:{0}", watch.ElapsedMilliseconds); watch.Restart(); var query2 = (from n in dic.Values.AsParallel()
where n.Age > && n.Age <
select n).ToList(); watch.Stop(); Console.WriteLine("并行计算耗费时间:{0}", watch.ElapsedMilliseconds); Console.Read();
} public static ConcurrentDictionary<int, Student> LoadData()
{
ConcurrentDictionary<int, Student> dic = new ConcurrentDictionary<int, Student>(); //预加载1500w条记录
Parallel.For(, , (i) =>
{
var single = new Student()
{
ID = i,
Name = "hxc" + i,
Age = i % ,
CreateTime = DateTime.Now.AddSeconds(i)
};
dic.TryAdd(i, single);
}); return dic;
} public class Student
{
public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } public DateTime CreateTime { get; set; }
}

orderby,sum(),average()等等这些聚合函数都是实现了并行化。

二、指定并行度

这个我在前面文章也说过,为了不让并行计算占用全部的硬件线程,或许可能要留一个线程做其他事情。

var query2 = (from n in dic.Values.AsParallel().WithDegreeOfParallelism(Environment.ProcessorCount - 1)
where n.Age >  && n.Age <
orderby n.CreateTime descending
select n).ToList();

三、了解ParallelEnumerable类

首先这个类是Enumerable的并行版本,提供了很多用于查询实现的一组方法,下图为ParallelEnumerable类的方法,记住他们都是并行的。

ConcurrentBag<int> bag = new ConcurrentBag<int>();
var list = ParallelEnumerable.Range
(, );
list.ForAll((i) =>
{
bag.Add(i);
}); Console.WriteLine("bag集合中元素个数有:{0}", bag.Count);
Console.WriteLine("list集合中元素个数总和为:{0}", list.Sum());
Console.WriteLine("list集合中元素最大值为:{0}", list.Max());
Console.WriteLine("list集合中元素第一个元素为:{0}", list.FirstOrDefault());

四、plinq实现MapReduce算法

mapReduce是一个非常流行的编程模型,用于大规模数据集的并行计算,非常的牛X啊,记得mongodb中就用到了这个玩意。

  • map:  也就是“映射”操作,可以为每一个数据项建立一个键值对,映射完后会形成一个键值对的集合。
  • reduce:“化简”操作,我们对这些巨大的“键值对集合“进行分组,统计等等。

下面我举个例子,用Mapreduce来实现一个对age的分组统计。

static void Main(string[] args)
{
List<Student> list = new List<Student>()
{
new Student(){ ID=, Name="jack", Age=},
new Student(){ ID=, Name="mary", Age=},
new Student(){ ID=, Name="joe", Age=},
new Student(){ ID=, Name="Aaron", Age=},
}; //这里我们会对age建立一组键值对
var map = list.AsParallel().ToLookup(i => i.Age, count => ); //化简统计
var reduce = from IGrouping<int, int> singleMap
in map.AsParallel()
select new
{
Age = singleMap.Key,
Count = singleMap.Count()
}; ///最后遍历
reduce.ForAll(i =>
{
Console.WriteLine("当前Age={0}的人数有:{1}人", i.Age, i.Count);
});
} public class Student
{
public int ID { get; set; } public string Name { get; set; } public int Age { get; set; } public DateTime CreateTime { get; set; }
}

考虑一个简单的例子,现有一个容量为1000000的单词集,需要我们以降序列出其中出现次数超过100000的单词(和其次数)。Map过程,使用PLINQ将集合按单词分组,这里使用了Lookup容器接口,它与Dictionary类似,但是提供的是键-值集映射;Reduce过程,使用PLINQ归约查询即可。

某一次运行结果如下:

Word: you, Count: 142416
Word: van, Count: 115816
Word: next, Count: 110228

四、并行编程 - 并行LINQ(PLINQ) 的使用。AsParallel的更多相关文章

  1. .NET并行编程 - 并行方式

    使用多线程可以利用多核CPU的计算能力,可以提供更好的程序响应能力,但是每个线程都有开销,需要注意控制线程的数量. 1. System.Threading.Thread 使用多线程最直接的是使用Sys ...

  2. 三、并行编程 - Task同步机制。TreadLocal类、Lock、Interlocked、Synchronization、ConcurrentQueue以及Barrier等

    在并行计算中,不可避免的会碰到多个任务共享变量,实例,集合.虽然task自带了两个方法:task.ContinueWith()和Task.Factory.ContinueWhenAll()来实现任务串 ...

  3. 二、并行编程 - Task任务

    任务,基于线程池.其使我们对并行编程变得更简单,且不用关心底层是怎么实现的.System.Threading.Tasks.Task类是Task Programming Library(TPL)中最核心 ...

  4. 一、并行编程 - 数据并行 System.Threading.Tasks.Parallel 类

    一.并行概念 1.并行编程 在.NET 4中的并行编程是依赖Task Parallel Library(后面简称为TPL) 实现的.在TPL中,最基本的执行单元是task(中文可以理解为"任 ...

  5. Java中的函数式编程(八)流Stream并行编程

    写在前面 在本系列文章的第一篇,我们提到了函数式编程的优点之一是"易于并发编程". Java作为一个多线程的语言,它通过 Stream 来提供了并发编程的便利性. 题外话: 严格来 ...

  6. C#并行编程-PLINQ:声明式数据并行

    目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C#并行编程-线程同步原语 C#并行编程-PLINQ:声明式数据并行 背景 通过LINQ可 ...

  7. C#并行编程-PLINQ:声明式数据并行-转载

    C#并行编程-PLINQ:声明式数据并行   目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C#并行编程-线程同步原语 C#并行编程-P ...

  8. Python并行编程(十四):异步编程

    1.基本概念 除了顺序执行和并行执行的模型以外,还有异步模型,这是事件驱动模型的基础.异步活动的执行模型可以只有一个单一的主控制流,能在单核心系统和多核心系统中运行. 在并发执行的异步模型中,许多任务 ...

  9. 《OpenCL异构并行编程实战》补充笔记散点,第一至四章

    ▶ 总体印象:适合 OpenCL 入门的书,有丰富的代码和说明,例子较为简单.先把 OpenCL 代码的基本结构(平台 → 设备 → 上下文 → 命令队列 → 创建缓冲区 → 读写缓冲区 → 编译代码 ...

随机推荐

  1. k8s中secret解析

    概览 Secret是用来保存小片敏感数据的k8s资源,例如密码,token,或者秘钥.这类数据当然也可以存放在Pod或者镜像中,但是放在Secret中是为了更方便的控制如何使用数据,并减少暴露的风险. ...

  2. memcached 学习笔记 2

    原理 1 核心组件 Memcached有两个核心组件组成:服务端(ms)和客户端(mc). 首先mc拿到ms列表,并对key做hash转化,根据hash值确定kv对所存的ms位置. 然后在一个memc ...

  3. Android6.0内核移植(1):分析编译日志

    在下面命令之后产生的编译日志进行分析 source build/envsetup.sh lunch sabresd_6dq-user make -j20 ======================= ...

  4. Linux 两个文件求交集、并集、差集

    一.交集 sort a.txt b.txt | uniq -d 二.并集 sort a.txt b.txt | uniq 三.差集 a.txt-b.txt: sort a.txt b.txt b.tx ...

  5. Java jxl导入excel文件,导入的数字、身份证号码、手机号变成了科学计数法,解决方案

    原文出自:https://blog.csdn.net/seesun2012 这是一个execl文件导入数据库操作,使用jxl解析execl导入数据库过程出现了科学计数法,与想要导入的数据不匹配,以下是 ...

  6. SQL Serever学习14——存储过程和触发器

    存储过程 在数据库中很多查询都是大同小异,编写他们费时费力,将他们保存起来,以后执行就很方便了,把SQL语句“封装”起来. 存储过程的概念 存储过程是一组SQL语句集,经过编译存储,可以”一次编译,多 ...

  7. Jquery中$与$.fn的区别

    Jquery中$与$.fn的区别 当今web开发往往离不开Jquery的使用,Jquery以其简洁的使用方式.良好的浏览器兼容性赢得了软件研发同行的青睐,作为其中的一员,自然也不例外,尽管刚开始时很排 ...

  8. SQL Server中的流控制语句

    begin···end 该语句定义sql代码块,通常在if和while语句中使用 declare @num int ; ; begin ; print 'hello word' end if···el ...

  9. 如何在没有https环境下使用webrtc

    新版本的webrtc使用需要Https,但是在内网开发调试时,要配置Https环境比较麻烦,下面的方法是教你如何在http下使用webrtc 1,点桌面上的Chrome图票,右键->属性,把目票 ...

  10. [LeetCode]Find Bottom Left Tree Value

    Find Bottom Left Tree Value: Given a binary tree, find the leftmost value in the last row of the tre ...