C#并行和合买平台搭建并行集合和PLinq

合买平台搭建

并行算法的出现,随之而产生的也就有了并行集合,及线程安全集合;微软向的也算周到,没有忘记linq,也推出了linq的并行版本,plinq - Parallel Linq.

一、并行集合 —— 线程安全集合

  并行计算使用的多个线程同时进行计算,所以要控制每个线程对资源的访问,我们先来看一下平时常用的List<T>集合,在并行计算下的表现,新建一个控制台应用程序,添加一个PEnumerable类(当然你也直接写到main方法里面测试,建议分开写),写如下方法:

复制代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;

namespace ThreadPool
{
public class PEnumerable
{
public static void ListWithParallel()
{
List<int> list = new List<int>();
Parallel.For(0, 10000, item =>
{
list.Add(item);
});
Console.WriteLine("List‘s count is {0}",list.Count());
}
}
}

复制代码

点击F5运行,得到如下结果:

看到结果中显示的5851,但是我们循环的是10000次啊!怎么结果不对呢?这是因为List<T>是非线程安全集合,意思就是说所有的线程都可以修改他的值。

下面我们来看下并行集合 —— 线程安全集合,在System.Collections.Concurrent命名空间中,首先来看一下ConcurrentBag<T>泛型集合,其用法和List<T>类似,先来写个方法测试一下:

复制代码

public static void ConcurrentBagWithPallel()
{
ConcurrentBag<int> list = new ConcurrentBag<int>();
Parallel.For(0, 10000, item =>
{
list.Add(item);
});
Console.WriteLine("ConcurrentBag‘s count is {0}", list.Count());
}

复制代码

同时执行两个方法,结果如下:

可以看到,ConcurrentBag集合的结果是正确的。下面我们修改代码看看ConcurrentBag里面的数据到底是怎么存放的,修改代码如下:

复制代码

public static void ConcurrentBagWithPallel()
{
ConcurrentBag<int> list = new ConcurrentBag<int>();
Parallel.For(0, 10000, item =>
{
list.Add(item);
});
Console.WriteLine("ConcurrentBag‘s count is {0}", list.Count());
int n = 0;
foreach(int i in list)
{
if (n > 10)
break;
n++;
Console.WriteLine("Item[{0}] = {1}",n,i);
}
Console.WriteLine("ConcurrentBag‘s max item is {0}", list.Max());

  }

复制代码

先来看一下运行结果:

可以看到,ConcurrentBag中的数据并不是按照顺序排列的,顺序是乱的,随机的。我们平时使用的Max、First、Last等linq方法都还有。其时分类似Enumerable的用法,大家可以参考微软的MSDN了解它的具体用法。

关于线程安全的集合还有很多,和我们平时用的集合都差不多,比如类似Dictionary的ConcurrentDictionary,还有ConcurrentStack,ConcurrentQueue等。

二、Parallel Linq的用法及性能

1、AsParallel

前面了解了并行的For和foreach,今天就来看一下Linq的并行版本是怎么样吧?为了测试,我们添加一个Custom类,代码如下:

public class Custom
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}

写如下测试代码:

复制代码

public static void TestPLinq()
{
Stopwatch sw = 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" });
}

     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);
  }

复制代码

其实也就是加了一个AsParallel()方法,下面来看下运行结果:

时间相差了一倍,不过有时候不会相差这么多,要看系统当前的资源利用率。大家可以多测试一下。

其实,AsParallel()这个方法可以应用与任何集合,包括List<T>集合,从而提高查询速度和系统性能。

2、GroupBy方法

在项目中,我们经常要对数据做处理,比如分组统计,我们知道在linq中也可以实现,今天来学习一下新的ToLookup方法,写一个测试方法,代码如下:

复制代码

public static void OrderByTest()
{
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);
  }

复制代码

运行结果如下:

ToLookup方法是将集合转换成一个只读集合,所以在大数据量分组时性能优于List.大家可以查阅相关资料,这里由于篇幅问题,不再细说。

原文地址:http://blog.51cto.com/13890757/2151164

时间: 2024-10-07 12:16:58

C#并行和合买平台搭建并行集合和PLinq的相关文章

unity访问合买平台搭建其他游戏对象的四种方式

一.通过属性合买平台搭建论坛:haozbbs.com Q1446595067 查看器指定参数访问其他游戏对象 将要旋转的物体拖到属性栏上的obj,运行就可以看到cube旋转 二.通过父子关系的相应函数访问其他游戏对象 当前对象是cylinder,其子对象是cube,该函数实现对其子对象的旋转 通过该函数实现对其父目录下的对象旋转,父对象为Cube 三.通过名字或者标签获取游戏对象 1.通过名字获取游戏对象 2.通过游戏对象的标签获取游戏对象 前提必须为要获取的游戏对象加上"cube"标

Dubbo服务合买平台搭建出售发布之服务暴露&amp;心跳机制&amp;服务注册

Dubbo服务发布 Dubbo合买平台搭建出售 dsluntan.com Q:3393756370 VX:17061863513服务发布影响流程的主要包括三个部分,依次是: 服务暴露 心跳 服务注册 服务暴露是对外提供服务及暴露端口,以便消费端可以正常调通服务.心跳机制保证服务器端及客户端正常长连接的保持,服务注册是向注册中心注册服务暴露服务的过程. Dubbo服务暴露 此处只记录主要代码部分以便能快速定位到主要的核心代码: ServiceConfig.java中代码 if (registryU

Nginx的正反向代理和合买平台出租配置文件详解

简述:合买平台出租 Q1446595067 Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.并在一个BSD-like 协议下发行,其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度.京东.新浪.网易.腾讯.淘宝等. 负载均衡的简述: 多台服务器处于一个内网,而我们要访问这些服务器,中间加一台 反向代理,根据各台服务器的负载,指定访问

Linux下bc平台搭建安装集群版Redis

之前bc平台搭建[企鹅21717-93408]安装了单机的Redis,这次安装一个Redis集群.集群定义: 多个业务单元一同工作,且每个业务单元都是相同的.集群特点: 当集群中业务单元大于等于1/2个凉了的时候,这个集群就不能再使用了,经过计算,当集群数为3的时候,整体down的几率最低一主一备模式,给每一个业务单元创建一个备用业务单元,原来的业务单元称作master,备用的称作slave.集群和伪集群: 集群:每一个业务单元在单独的服务器上伪集群:所有的业务单元都在同一个服务器上,用端口号来

Linux上北京-赛车平台搭建分布式集群

1.下载北京-赛车平台源码搭建 2.通过Xftp将文件传到Linux服务器上 3.使用 命令 tar --zxvf zookeeper-3.4.12 解压 zookeeper 4.配置系统环境变量 vim /etc/profile 执行source /etc/profile 使环境变量立即生效5.进入conf中 复制 zoo_sample.cfg 文件的并命名为为 zoo.cfg 6.同过 vim zoo.cfg 编辑配置文件 编辑前 编辑后 server.A=B:C:D中的A是一个数字,表示这

5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq

在上一篇博客5天玩转C#并行和多线程编程 —— 第一天 认识Parallel中,我们学习了Parallel的用法.并行编程,本质上是多线程的编程,那么当多个线程同时处理一个任务的时候,必然会出现资源访问问题,及所谓的线程安全.就像现实中,我们开发项目,就是一个并行的例子,把不同的模块分给不同的人,同时进行,才能在短的时间内做出大的项目.如果大家都只管自己写自己的代码,写完后发现合并不到一起,那么这种并行就没有了意义. 并行算法的出现,随之而产生的也就有了并行集合,及线程安全集合:微软向的也算周到

MySQL集群---②Windows平台搭建MySQL CLUSTER集群

本文将通过两台电脑来简单介绍一下Windows平台如何搭建MySQL集群. MySQL集群支持多台电脑,本文搭建的MySQL集群以两台机子为例,其中一台(IP为192.168.24.33)部署管理节点.数据节点和SQL节点,另一台(IP为192.168.24.82)部署数据节点和SQL节点. 实际应用中,不要将管理节点跟数据节点部署到一台机子上,因为如果数据节点宕机会导致管理节点不可用,同时整个MySQL群集也就都不可用了.所以一个MySQL群集理想情况下至少有三台服务器,将管理节点单独放到一台

Hadoop集群大数据平台搭建

Hadoop集群环境搭建配置 前言 Hadoop的搭建分为三种形式:单机模式.伪分布模式.完全分布模式,只要掌握了完全分布模式,也就是集群模式的搭建,剩下的两种模式自然而然就会用了,一般前两种模式一般用在开发或测试环境下,Hadoop最大的优势就是分布式集群计算,所以在生产环境下都是搭建的最后一种模式:完全分布模式. 硬件选择 须知: 分布式环境中一个服务器就是一个节点 节点越多带来的是集群性能的提升 一个Hadoop集群环境中,NameNode,SecondaryNameNode和DataNo

基于Hama平台的并行Finding a Maximal Independent Set 算法的设计与实现

作者:白松 西工大研究生.转载请注明出处:http://blog.csdn.net/xin_jmail/article/details/32101483. 本文参加了2014年CSDN博文大赛,如果您觉得此文对您有所帮助,就请为我投上您宝贵的一票,不胜感激.投票地址:http://vote.blog.csdn.net/Article/Details?articleid=32101483 . 本文目的:讲解并行Finding a Maximal Independent Set(寻找最大独立集问题)