C#并行和合買平臺搭建并行集合和PLinq-創(chuàng)新互聯(lián)

合買平臺搭建

創(chuàng)新互聯(lián)于2013年開始,先為渠縣等服務(wù)建站,渠縣等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為渠縣企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

并行算法的出現(xiàn),隨之而產(chǎn)生的也就有了并行集合,及線程安全集合;微軟向的也算周到,沒有忘記linq,也推出了linq的并行版本,plinq - Parallel Linq.

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

并行計算使用的多個線程同時進(jìn)行計算,所以要控制每個線程對資源的訪問,我們先來看一下平時常用的List<T>集合,在并行計算下的表現(xiàn),新建一個控制臺應(yīng)用程序,添加一個PEnumerable類(當(dāng)然你也直接寫到main方法里面測試,建議分開寫),寫如下方法:

復(fù)制代碼

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

復(fù)制代碼

點擊F5運行,得到如下結(jié)果:

看到結(jié)果中顯示的5851,但是我們循環(huán)的是10000次啊!怎么結(jié)果不對呢?這是因為List<T>是非線程安全集合,意思就是說所有的線程都可以修改他的值。

下面我們來看下并行集合 —— 線程安全集合,在System.Collections.Concurrent命名空間中,首先來看一下ConcurrentBag<T>泛型集合,其用法和List<T>類似,先來寫個方法測試一下:

復(fù)制代碼

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

復(fù)制代碼

同時執(zhí)行兩個方法,結(jié)果如下:

可以看到,ConcurrentBag集合的結(jié)果是正確的。下面我們修改代碼看看ConcurrentBag里面的數(shù)據(jù)到底是怎么存放的,修改代碼如下:

復(fù)制代碼

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

  }

復(fù)制代碼

先來看一下運行結(jié)果:

可以看到,ConcurrentBag中的數(shù)據(jù)并不是按照順序排列的,順序是亂的,隨機(jī)的。我們平時使用的Max、First、Last等linq方法都還有。其時分類似Enumerable的用法,大家可以參考微軟的MSDN了解它的具體用法。

關(guān)于線程安全的集合還有很多,和我們平時用的集合都差不多,比如類似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; }
}

寫如下測試代碼:

復(fù)制代碼

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

復(fù)制代碼

其實也就是加了一個AsParallel()方法,下面來看下運行結(jié)果:

時間相差了一倍,不過有時候不會相差這么多,要看系統(tǒng)當(dāng)前的資源利用率。大家可以多測試一下。

其實,AsParallel()這個方法可以應(yīng)用與任何集合,包括List<T>集合,從而提高查詢速度和系統(tǒng)性能。

2、GroupBy方法

在項目中,我們經(jīng)常要對數(shù)據(jù)做處理,比如分組統(tǒng)計,我們知道在linq中也可以實現(xiàn),今天來學(xué)習(xí)一下新的ToLookup方法,寫一個測試方法,代碼如下:

復(fù)制代碼

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

復(fù)制代碼

運行結(jié)果如下:

ToLookup方法是將集合轉(zhuǎn)換成一個只讀集合,所以在大數(shù)據(jù)量分組時性能優(yōu)于List.大家可以查閱相關(guān)資料,這里由于篇幅問題,不再細(xì)說。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

分享名稱:C#并行和合買平臺搭建并行集合和PLinq-創(chuàng)新互聯(lián)
標(biāo)題鏈接:http://bm7419.com/article2/cdieic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、品牌網(wǎng)站建設(shè)網(wǎng)站維護(hù)、Google、外貿(mào)建站微信公眾號

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)