用于对内存中的数据做并行运算,也就是说其只支持 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. log4php0.9的详细配备实例说明

    一.什么是log4php: log4j在JAVA中可算是大名鼎鼎的日志开发包了,它为apche组织维护项目,VxR兄使用php来实现了log4j的功能, 目前log4php已经作为log4j的一个子项 ...

  2. 一起来做Chrome Extension《搭个架子》

    CEF - A simple Chrome Extension development falsework CEF是一个简单的Chrome Extension开发脚手架,它有如下功能: 模块化的结构, ...

  3. 微信小程序 c#后台支付结果回调

    又为大家带来简单的c#后台支付结果回调方法,首先还是要去微信官网下载模板(WxPayAPI),将模板(WxPayAPI)添加到服务器上,然后在打开WxPayAPI项目中的example文件下的 Nat ...

  4. Vue学习笔记:编译过程

    碰到是否有template选项时,会询问是否要对template进行编译: 在template编译(渲染成UI)有一个过程.模板通过编译生成AST,再由AST生成Vue的渲染函数,渲染函数结合数据生成 ...

  5. C#中区别多态、重载、重写

    重写是指重写基类的方法,在基类中的方法必须有修饰符virtual,而在子类的方法中必须指明override. 格式: 基类中: public virtual void myMethod() { } 子 ...

  6. groovy集合

    groovy集合可以直接在语言中使用,因为它默认已经导入包了. 不需要初始化对象,也不需要专门的类. 集合是groovy语言本地成员.Groovy语法提供了本地列表和相应的映射. 每个Groovy集合 ...

  7. JSP简单实现统计网页访问次数

    JSP简单实现统计网页访问次数 需求:统计网页的访问次数 核心思想:利用application对象,将访问次数的信息放入application对象中,每次访问就+1.这里利用了application对 ...

  8. oauth2.0授权协议

    参考文章 一.OAuth是什么? OAuth的英文全称是Open Authorization,它是一种开放授权协议.OAuth目前共有2个版本,2007年12月的1.0版(之后有一个修正版1.0a)和 ...

  9. sublime Text3汉化和激活注册码

    sublimeText3 很不错,前面几天下了vscore学习Node.js,感觉有点懵,今天下载sublimeText3,遇到的一些小问题,在这里说说: 百度云:https://pan.baidu. ...

  10. MSSQL中的表变量

    最近在看<Microsoft SQL Server2005技术内幕:T-SQL程序设计> 1.表变量的事务上下文中提到,表变量不受外部事务回滚影响. 举个例子: DECLARE  @TA ...