[C#]『PLINQ』任务并行库使用小计
并行 LINQ (PLINQ) 是 LINQ to Objects 的并行实现。 PLINQ 实现完整的 LINQ 标准查询运算符集作为 T:System.Linq 命名空间的扩展方法,并具有用于并行运算的其他运算符。 PLINQ 将 LINQ 语法的简洁和可靠性与并行编程的强大功能结合在一起。 就像面向任务并行库的代码一样,PLINQ 查询会根据主计算机的能力按比例调整并发程度。
在许多情况下,PLINQ 可通过更有效地使用主计算机上的所有可用内核来显著提高 LINQ to Objects 查询的速度。 这一性能提升将使桌面具备高性能计算能力。
为了实现加速,PLINQ 查询必须具有足够的适合并行工作来弥补开销。 工作可表示为每个委托的计算开销与源集合中元素数量的乘积。 假定某个操作可并行化,则它的计算开销越高,加速的可能性就越大。 例如,如果某个函数执行花费的时间为 1 毫秒,则针对 1000 个元素进行的顺序查询将花费 1 秒来执行该操作,而在四核计算机上进行的并行查询可能只花费 250 毫秒。 这样就产生了 750 毫秒的加速。 如果该函数对于每个元素需要花费 1 秒来执行,则加速将为 750 秒。 如果委托的开销很大,则对于源集合中的很少几个项,PLINQ 可能会提供明显的加速。 相反,包含无关紧要委托的小型源集合通常不适合于 PLINQ。 ——MSDN
1.普通示例
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace PLinq
{
class Program
{
static IList<Person> _persons = new List<Person>();
static void Main(string[] args)
{
try
{
CreateTextDB();
PLINQ_Where();
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim()));
}
finally
{
Console.ReadLine();
}
}
/// <summary>
/// 筛选
/// </summary>
private static void PLINQ_Where()
{
Stopwatch _wacth = new Stopwatch();
_wacth.Start();
IList<Person> _personWhereNormal = _persons.Where(p => p.Age > 10 && p.Age < 50).ToList();
_wacth.Stop();
Console.WriteLine(string.Format("Normal LINQ Where Cost Time:{0}", _wacth.ElapsedMilliseconds));
_wacth.Restart();
//WithDegreeOfParallelism
IList<Person> _personWhereParallel = _persons.AsParallel<Person>().Where(p => p.Age > 10 && p.Age < 50).ToList();
_wacth.Stop();
Console.WriteLine(string.Format("PLINQ Where Cost Time:{0}", _wacth.ElapsedMilliseconds));
}
/// <summary>
/// 创建测试数据
/// </summary>
private static void CreateTextDB()
{
Stopwatch _wacth = new Stopwatch();
_wacth.Start();
Parallel.For(0, 10000000, (i, loopstatus) =>
{
Person _person = new Person();
_person.FristName = "Yan";
_person.LastName = string.Format("Zhiwei {0}", i);
_person.RegisterTime = DateTime.Now;
_person.Age = i;
lock (((ICollection)_persons).SyncRoot)
{
_persons.Add(_person);
}
});
_wacth.Stop();
Console.WriteLine(string.Format("Create TextDB Cost Time:{0},Count:{1}", _wacth.ElapsedMilliseconds, _persons.Count));
}
}
class Person
{
public string FristName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public DateTime RegisterTime { get; set; }
}
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }代码效果
2.异常处理
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; namespace PLinq { class Program { static IList<Person> _persons = new List<Person>(); static void Main(string[] args) { try { CreateTextDB(); PINQ_Exception(); } catch (Exception ex) { Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim())); } finally { Console.ReadLine(); } } private static void PINQ_Exception() { /* * 这样处理,当出现异常的时候不会影响下次foralll遍历 */ Func<int, bool> isTure = (age) => { try { if (age > 1989222) throw new Exception("PLINQ Text"); Console.WriteLine(age); return true; } catch (Exception ex) { Console.WriteLine(ex.Message); return false; } }; _persons.AsParallel<Person>().ForAll(p => isTure(p.Age)); } /// <summary> /// 创建测试数据 /// </summary> private static void CreateTextDB() { Stopwatch _wacth = new Stopwatch(); _wacth.Start(); Parallel.For(0, 10000000, (i, loopstatus) => { Person _person = new Person(); _person.FristName = "Yan"; _person.LastName = string.Format("Zhiwei {0}", i); _person.RegisterTime = DateTime.Now; _person.Age = i; lock (((ICollection)_persons).SyncRoot) { _persons.Add(_person); } }); _wacth.Stop(); Console.WriteLine(string.Format("Create TextDB Cost Time:{0},Count:{1}", _wacth.ElapsedMilliseconds, _persons.Count)); } } class Person { public string FristName { get; set; } public string LastName { get; set; } public int Age { get; set; } public DateTime RegisterTime { get; set; } } }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
代码效果
3.取消 PLINQ 查询
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace PLinq { class Program { static IList<Person> _persons = new List<Person>(); static void Main(string[] args) { try { CreateTextDB(); PINQ_Cancellation(); } catch (Exception ex) { Console.WriteLine(string.Format("Exception Message:{0}", ex.Message.Trim())); } finally { Console.ReadLine(); } } private static void PINQ_Cancellation() { try { /* * 当您在用户代码中处理取消时,不必在查询定义中使用 WithCancellation<TSource>。 但是,我们建议您这样做,原因是 WithCancellation<TSource> 对查询性能没有影响, * 并且它使取消能够由查询运算符和用户代码进行处理。 为了确保系统响应能力,我们建议您大约每毫秒检查是否存在取消一次; * 不过,任何 10 毫秒以下的期间都被视为可接受。 此频率对代码的性能应没有负面影响。 ——MSDN */ CancellationTokenSource _cancel = new CancellationTokenSource(); Func<int, bool> isTure = (age) => { if (age > 1989222) _cancel.Cancel(); Console.WriteLine(age); return true; }; _persons.AsParallel<Person>().WithCancellation(_cancel.Token).ForAll(p => isTure(p.Age)); } catch (OperationCanceledException ex) { Console.WriteLine(string.Format("OperationCanceledException Message:{0}", ex.Message)); } } /// <summary> /// 创建测试数据 /// </summary> private static void CreateTextDB() { Stopwatch _wacth = new Stopwatch(); _wacth.Start(); Parallel.For(0, 10000000, (i, loopstatus) => { Person _person = new Person(); _person.FristName = "Yan"; _person.LastName = string.Format("Zhiwei {0}", i); _person.RegisterTime = DateTime.Now; _person.Age = i; lock (((ICollection)_persons).SyncRoot) { _persons.Add(_person); } }); _wacth.Stop(); Console.WriteLine(string.Format("Create TextDB Cost Time:{0},Count:{1}", _wacth.ElapsedMilliseconds, _persons.Count)); } } class Person { public string FristName { get; set; } public string LastName { get; set; } public int Age { get; set; } public DateTime RegisterTime { get; set; } } }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
代码效果
[C#]『PLINQ』任务并行库使用小计的更多相关文章
- [C#]『CountdownEvent』任务并行库使用小计
System.Threading.CountdownEvent 是一个同步基元,它在收到一定次数的信号之后,将会解除对其等待线程的锁定. CountdownEvent 专门用于以下情况:您必须使用 ...
- [C#]『Barrier』任务并行库使用小计
Barrier 是一个对象,它可以在并行操作中的所有任务都达到相应的关卡之前,阻止各个任务继续执行. 如果并行操作是分阶段执行的,并且每一阶段要求各任务之间进行同步,则可以使用该对象. --MSDN ...
- [C#]『Task』任务并行库使用小计
1.简单创建使用 using System; using System.Diagnostics; using System.Threading; using System.Threading.Task ...
- C# 任务并行库使用小计 z
1.简单创建使用 using System; using System.Diagnostics; using System.Threading; using System.Threading.Task ...
- 『计算机视觉』imgaug图像增强库中部分API简介
https://github.com/aleju/imgaug 介绍一下官方demo中用到的几个变换,工程README.md已经给出了API简介,个人觉得不好理解,特此单独记录一下: import n ...
- C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式)
学习书籍: <C#本质论> 1--C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是 ...
- 『TensorFlow』分布式训练_其二_单机多GPU并行&GPU模式设定
建议比对『MXNet』第七弹_多GPU并行程序设计 一.tensorflow GPU设置 GPU指定占用 gpu_options = tf.GPUOptions(per_process_gpu_mem ...
- 『开源』Slithice 2013 服务器集群 设计和源码
相关介绍文章: <『设计』Slithice 分布式架构设计-支持一体式开发,分布式发布> <『集群』001 Slithice 服务器集群 概述> <『集群』002 Sli ...
- 『计算机视觉』Mask-RCNN_推断网络其四:FPN和ROIAlign的耦合
一.模块概述 上节的最后,我们进行了如下操作获取了有限的proposal, # [IMAGES_PER_GPU, num_rois, (y1, x1, y2, x2)] # IMAGES_PER_GP ...
随机推荐
- 在CentOS6上安装Redis
检查安装依赖程序 yum install -y gcc-c++ tcl wget 获取安装文件 wget http://download.redis.io/releases/redis-2.8.17. ...
- android 文件读取(assets、raw)
需要注意的是,来自Resources和Assets 中的文件只可以读取而不能进行写的操作. assets文件夹里面的文件都是保持原始的文件格式,需要用AssetManager以字节流的形式读取文件. ...
- VC中获取窗体句柄的各种方法
AfxGetMainWnd AfxGetMainWnd获取自身窗体句柄 HWND hWnd = AfxGetMainWnd()->m_hWnd; GetTopWindow 函数功能:该函数检查与 ...
- 【代码优化】坚持使用Override注解
对于传统程序猿,注解里面最重要的就是Override注解了.这里的注解,都是指仅仅能用在方法中的声明, 她表示被注解的方法用于覆盖了父类的一个声明,假设坚持使用这个注解,能够防止一大类的非法错误. & ...
- android开发入门经验 ADT Bundle环境搭建
现在有许多做开发的转做移动端开发,做J2EE的转做Android开发,我也把自己的一些入门经验与大家分享一下,希望能给你带来帮助. 工具/原料 JDK,ADT,JAVA 方法/步骤 开发工具的准备 ...
- mysql优化之查询优化
Posted by Money Talks on 2012/02/24 | 第一篇 序章第二篇 连接优化第三篇 索引优化第四片 查询优化第五篇 到实战中去 查询优化 查询优化涉及到用户查询数据时使用到 ...
- Executing System commands in Java---ref
One of the nice features of Java language is that it provides you the opportunity to execute native ...
- phpcms 源码分析三:common.inc.php
这次是逆雪寒分析common.inc.php的数据库部分: <?php // 包含数据库操作类,下章详说 require PHPCMS_ROOT.'/include/'.$db_file.'.c ...
- 正确的使用枚举(Enum)
状态与选项的区别(states and options) 在用enum之前,我个人觉得,区分一下状态和选项的概念还是很必要的. 状态,同时只能有一种,如“OK”,“Error”,不可能同时是OK和Er ...
- jQuery动态实现title的修改 失效问题
最近做了一个网站,一切都很顺利,在上线的时候,突然发现一个严重的问题,开始面对这个问题,完全不知所措(在goole.火狐.IE9及其以上都没得问题:IE8及其低版本都失效)只是浏览器弹出一个bug,但 ...