C#编程(六十三)----------并行LINQ
并行LINQ
.NET4在System.Linq命名空间中包含一个新类ParallelEnumerable,可以分解查询的工作使其分布在多个线程上.尽管Enumerable类给IEnumerable<T>接口定义了扩展方法,但ParallelEnumerable类的大多数扩展方法是ParallelQuery<TSource>类的扩展.一个重要的例外是AsParallel()方法,它扩展了IEnumerable<TSource>接口,返回ParallelQuery<TSource>类,所以正常的集合类可以以平行方式查询.
LINQ比较强大的是还提供了可并行处理的查询,这使得我们可以借助它来完成一些查询处理或处理并行操作.
先来说一下并行集合,并行计算使用的多个线程同时进行计算,所以要控制每个线程对资源的访问,我们先来看一下常用的List<T>集合,在并行计算下的表示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 并行集合和LINQ
{
class Program
{
static void Main(string[] args)
{
List<int> list = new List<int>();
Parallel.For(0, 10000, item =>
{
list.Add(item);
}
);
Console.WriteLine("list的长度为 : {0}",list.Count());
//多测试几次,就是说多运行几次
/*
* 从结构可以看出,我们的结构不是10000.这是为什么呢,这是因为List是费线程安全的
* ,也就是说,任何线程都可以修改他的值
*/
Console.ReadKey();
}
}
}
接下来我们看一下并行集合----线程安全集合,在System.Collections.Concurrent命名空间中,首先看一下ConcurrentBag<T>泛型集合,其用法和List<T>类似:
ConcurrentBag<int> list =new ConcurrentBag<int>();
Parallel.For(0, 10000, item =>
{
list.Add(item);
}
);
Console.WriteLine("ConcurrentBag的长度为 : {0}", list.Count());
//不管运行几次,结果都是10000
分析一下,因为ConcurrentBag是线程安全的,所以每次结果都是正确的.
下面我们来修改代码看看ConcurrentBag里面的数据到底是怎样存放的,修改代码如下:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 并行集合和LINQ
{
class Program
{
static void Main(string[] args)
{
ConcurrentBag<int> list =new ConcurrentBag<int>();
Parallel.For(0, 10000, item =>
{
list.Add(item);
}
);
Console.WriteLine("ConcurrentBag的长度为 : {0}", list.Count());
//不管运行几次,结果都是10000
int n = 0;
foreach (var item in list)
{
if (n>10)
{
break;
}
n++;
Console.WriteLine("Item[{0}] = {1}",n,item);//,多运行几次,观察这里的输出
}
Console.WriteLine("ConcurrentBag的最大长度为 : {0}",list.Max());
Console.ReadKey();
}
}
}
分析:可以看到ConcurrentBag中的数据并不是按照顺序排列的,顺序是乱的,随机的.我们平时使用的Max,First,Last等LINQ方法都还有.其十分类似Enumerable的用法.
关于线程安全的集合还有很多,和我们平时用的集合都差不多,比如类似Dictionary的ConcurrentDictionary,还有ConcurrentStack,ConcurrentQueue等。
并行LINQ的用法和性能
1.AsParallel
案例:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 并行集合和LINQ
{
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();//需要添加命名空间 System.Threading.Tasks;
List<Custom> customs = new List<Custom>();
for (int i = 0; i < 2000000; i++)
{
customs.Add(new Custom() { Name = "Jack", Age = 21, Address = "NewYork" });
customs.Add(new Custom() { Name = "Jime", Age = 26, Address = "China" });
customs.Add(new Custom() { Name = "Tina", Age = 29, Address = "ShangHai" });
customs.Add(new Custom() { Name = "Luo", Age = 30, Address = "Beijing" });
customs.Add(new Custom() { Name = "Wang", Age = 60, Address = "Guangdong" });
customs.Add(new Custom() { Name = "Feng", Age = 25, Address = "YunNan" });
}
sw.Start();
var result = customs.Where<Custom>(c => c.Age > 26).ToList();
sw.Stop();
Console.WriteLine("Linq time is {0}.", sw.ElapsedMilliseconds);
sw.Restart();
sw.Start();
var result2 = customs.AsParallel().Where<Custom>(c => c.Age > 26).ToList();
sw.Stop();
Console.WriteLine("Parallel Linq time is {0}.", sw.ElapsedMilliseconds);
Console.WriteLine("运行完毕");//这句话可能需要过一会才能出现
Console.ReadKey();
}
}
public class Custom
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
}
分析:多运行即便可以发现,添加了AsParallel()方法的速度差不多快了一倍.其实,AsParallel()这个方法可以应用与任何集合,包括List<T>集合,从而提高查询速度和系统性能。
2.GroupBy方法
在项目中,我们经常要对数据做处理,比如分组统计,我们知道在LINQ中也可以实现,今天来学习以下新的ToLookUp方法,写一个测试方法:其他代码相似,只是测试代码不同
Stopwatch stopWatch = new Stopwatch();
List<Custom> customs = new List<Custom>();
for (int i = 0; i < 2000000; i++)
{
customs.Add(new Custom() { Name = "Jack", Age = 21, Address = "NewYork" });
customs.Add(new Custom() { Name = "Jime", Age = 26, Address = "China" });
customs.Add(new Custom() { Name = "Tina", Age = 29, Address = "ShangHai" });
customs.Add(new Custom() { Name = "Luo", Age = 30, Address = "Beijing" });
customs.Add(new Custom() { Name = "Wang", Age = 60, Address = "Guangdong" });
customs.Add(new Custom() { Name = "Feng", Age = 25, Address = "YunNan" });
}
stopWatch.Restart();
var groupByAge = customs.GroupBy(item => item.Age).ToList();
foreach (var item in groupByAge)
{
Console.WriteLine("Age={0},count = {1}", item.Key, item.Count());
}
stopWatch.Stop();
Console.WriteLine("Linq group by time is: " + stopWatch.ElapsedMilliseconds);
stopWatch.Restart();
var lookupList = customs.ToLookup(i => i.Age);
foreach (var item in lookupList)
{
Console.WriteLine("LookUP:Age={0},count = {1}", item.Key, item.Count());
}
stopWatch.Stop();
Console.WriteLine("LookUp group by time is: " + stopWatch.ElapsedMilliseconds);
Console.WriteLine("运行完毕");//这句话可能需要过一会才能出现
Console.ReadKey();
ToLookup方法是将集合转换成一个只读集合,所以在大数据量分组时性能优于List.
C#编程(六十三)----------并行LINQ的更多相关文章
- 四、并行编程 - 并行LINQ(PLINQ) 的使用。AsParallel
用于对内存中的数据做并行运算,也就是说其只支持 LINQ to Object 的并行运算 一.AsParallel(并行化) 就是在集合后加个AsParallel(). 例如: , ); == ); ...
- 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq
5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编 ...
- 孤荷凌寒自学python第六十三天学习mongoDB的基本操作并进行简单封装2
孤荷凌寒自学python第六十三天学习mongoDB的基本操作并进行简单封装2 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第九天. 今天继续学习mongoDB的简单操作, ...
- 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). 其次是 ...
- 并行Linq(一)
.Net 并行计算 ----并行Linq(一) 本文是.Net 并行计算 的第三篇 欢迎大家拍砖,阅读本文需要有LINQ基础,因为并行LINQ (PLinq) 其实是LINQ To Object 的并 ...
- JDBC编程六部曲
今天初学jdbc,明白了大致的编程流程,在此总结一下: JDBC编程可以分为六步——六部曲: * 第一步:注册驱动. * 1.1 获取驱动对象 * 1.2 注册驱动 * 第二步:获取数据库连接 * 第 ...
- C# 多线程八之并行Linq(ParallelEnumerable)
1.简介 关于并行Linq,Ms官方叫做并行语言集成(PLINQ)查询,其实本质就是Linq的多线程版本,常规的Linq是单线程的,也就是同步的过程处理完所有的查询.如果你的Linq查询足够简单,而且 ...
- 并行Linq
有时候我们对大批量数据进行处理,此时并行linq就起作用了. 并行查询 对于以下查询可以耗时会非常大,如下: ; var r = new Random(); , arraySize).Select(x ...
- “全栈2019”Java第六十三章:接口与抽象方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
随机推荐
- (转载)mysql:“Access denied for user 'root'@'localhost'”
原文地址:http://www.linuxidc.com/Linux/2007-05/4338.htm # /etc/init.d/mysql stop# mysqld_safe --user=mys ...
- Linux屏幕记录命令script
Script -a action.log –t 2> time.log按ctrl+d 退出录制回访 scriptreplay time.log action.log或者直接用查看命令cat,ta ...
- PHP中curl模拟post上传及接收文件
public function Action_Upload(){ $this->path_config(); exit(); $furl="@d:\develop\JMFramewor ...
- HTML5+ App开发入门
HTML5 Plus应用概述 HTML5 Plus移动App,简称5+App,是一种基于HTML.JS.CSS编写的运行于手机端的App,这种App可以通过扩展的JS API任意调用手机的原生能力,实 ...
- Struts2与Spring的Maven依赖冲突
今天在用Maven集成Struts2+Spring+Hibernate时发现只要不在web模块中声明spring-web的依赖,就会报java.lang.NoClassDefFoundError: [ ...
- bzoj 1150
思路:写的时候感觉是贪心但是没有什么思路... 看了题解,原来有一个选了能反悔的贪心思路, 如果最优那么每个城市只能和旁边的相邻 城市连边,所以问题变成了由n个数,不能取相邻的两个数,取k个最小是多少 ...
- oracle11g数据库升级数据库升级
Oracle对自己产品也一样,对于自己的产品在不同的时期,支持的强度是不一样的.大体分来,支持的强度分为三个级别:Premier Support(最高优先级的支持),Extended Support( ...
- thinkphp中table方法
table方法也属于模型类的连贯操作方法之一,主要用于指定操作的数据表. 用法 一般情况下,操作模型的时候系统能够自动识别当前对应的数据表,所以,使用table方法的情况通常是为了:切换操作的数据表: ...
- 访问url下载文件----python
工作上有时候有需求,会下载pdf,doc,zip等文件,可以用以下方法,推荐使用第一种 下载文件: import urllib import urllib2 import requests url = ...
- 026.Zabbix简单调优
一 调优相关对应项 Zabbix busy trapper processes, in % StartTrappers=5 Zabbix busy poller processes, in % Sta ...