四、并行编程 - 并行LINQ(PLINQ) 的使用。AsParallel
- 一、并行编程 - 数据并行 System.Threading.Tasks.Parallel 类
- 二、并行编程 - Task任务
- 三、并行编程 - Task同步机制。TreadLocal类、Lock、Interlocked、Synchronization、ConcurrentQueue以及Barrier等
- 四、并行编程 - 并行LINQ(PLINQ) 的使用。AsParallel
- 五、并行编程 - 信号量
用于对内存中的数据做并行运算,也就是说其只支持 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的更多相关文章
- .NET并行编程 - 并行方式
使用多线程可以利用多核CPU的计算能力,可以提供更好的程序响应能力,但是每个线程都有开销,需要注意控制线程的数量. 1. System.Threading.Thread 使用多线程最直接的是使用Sys ...
- 三、并行编程 - Task同步机制。TreadLocal类、Lock、Interlocked、Synchronization、ConcurrentQueue以及Barrier等
在并行计算中,不可避免的会碰到多个任务共享变量,实例,集合.虽然task自带了两个方法:task.ContinueWith()和Task.Factory.ContinueWhenAll()来实现任务串 ...
- 二、并行编程 - Task任务
任务,基于线程池.其使我们对并行编程变得更简单,且不用关心底层是怎么实现的.System.Threading.Tasks.Task类是Task Programming Library(TPL)中最核心 ...
- 一、并行编程 - 数据并行 System.Threading.Tasks.Parallel 类
一.并行概念 1.并行编程 在.NET 4中的并行编程是依赖Task Parallel Library(后面简称为TPL) 实现的.在TPL中,最基本的执行单元是task(中文可以理解为"任 ...
- Java中的函数式编程(八)流Stream并行编程
写在前面 在本系列文章的第一篇,我们提到了函数式编程的优点之一是"易于并发编程". Java作为一个多线程的语言,它通过 Stream 来提供了并发编程的便利性. 题外话: 严格来 ...
- C#并行编程-PLINQ:声明式数据并行
目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C#并行编程-线程同步原语 C#并行编程-PLINQ:声明式数据并行 背景 通过LINQ可 ...
- C#并行编程-PLINQ:声明式数据并行-转载
C#并行编程-PLINQ:声明式数据并行 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C#并行编程-线程同步原语 C#并行编程-P ...
- Python并行编程(十四):异步编程
1.基本概念 除了顺序执行和并行执行的模型以外,还有异步模型,这是事件驱动模型的基础.异步活动的执行模型可以只有一个单一的主控制流,能在单核心系统和多核心系统中运行. 在并发执行的异步模型中,许多任务 ...
- 《OpenCL异构并行编程实战》补充笔记散点,第一至四章
▶ 总体印象:适合 OpenCL 入门的书,有丰富的代码和说明,例子较为简单.先把 OpenCL 代码的基本结构(平台 → 设备 → 上下文 → 命令队列 → 创建缓冲区 → 读写缓冲区 → 编译代码 ...
随机推荐
- Linux系统快速查找文件
有时候下载新的文件或安装新的包 但是却搞不清默认放在哪个目录了,这个时候可以使用locate命令进行快速模糊查找 比如我使用 go get github.com/coreos/bbolt/... 在一 ...
- MTCNN 实现人脸识别
MTCNN(Multi-task CNN) MTCNN难点 WIDER FACE等数据集为我们提供的图片并不是MTCNN支持的训练样本, 需要通过几个脚本将其转为MTCNN可以接受的数据集, 这些脚本 ...
- echart.js 参数解释
Data参数 获取容器对象 var canvas = document.getElementById("myCanvas"); 渲染 var ctx = canvas.getCon ...
- WCF中的AddressHeader作用
客户端发送请求给服务端,服务端根据请求消息把消息转发给对应的终结点.这里面有个消息筛选机制,如果请求消息中带有地址报头相关信息,则会用地址报头匹配当前的所有终结点.所以默认情况下客户端和服务端的地址报 ...
- 十八、fork/join框架
一.简介 在hadoop的分布式计算框架MapReduce中,会经过两个过程Map过程和reduce过程.Map过程将任务并行计算,reduce汇总并行计算的结果,如图: MapReduce是在分布式 ...
- poj 1811 Prime Test 大数素数测试+大数因子分解
Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 27129 Accepted: 6713 Case ...
- unity3d之简单的时钟倒计时demo
输入结束时间,开始倒计时,时间差不超过一天,附上代码:(关于个位数显示,加个判断如果小于10 显示的字符串加上0) using System.Collections; using System.Col ...
- java设计模式-----4、单例模式
单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的一个实例对象.也就是说,在整个程序空间中,该类只存在一个实例对象. 其实,GoF对单例模式的定义是:保证一个类,只有一个实例存在 ...
- ES6学习笔记(三)-正则扩展
PS: 前段时间转入有道云笔记,体验非常友好,所以笔记一般记录于云笔记中,每隔一段时间,会整理一下, 发在博客上与大家一起分享,交流和学习. 以下:
- 第九天- 文件操作 r w a 文件复制/修改
文件操作简介:使用python来读写文件是非常简单的操作.我们使用 open() 函数来打开一个文件,获取到文件句柄.然后通过文件句柄就可以进行各种各样的操作了.根据打开⽅方式的不同能够执行的操作也会 ...