PLINQ和LINQ的語法基本是差不多的,PLINQ該如何實現並行
var query = from item in source.AsParallel() where Compute(item) > 42 select item;
一個簡單的AsParallel方法就能實現並行運行,要聲明的是AsParallel方法返回的是ParallelEnumerable而不是Enumerable,如GO語言的go關鍵字一般簡單,雖然我怎么學過go語言,但我知道GO關鍵字絕對不會這么簡單,同樣PLINQ並行一樣不是這么簡單,雖然兩個不是一個級別的吧。必須要說明的是不要盲目的使用PLNQ,PLINQ會對輸入元素進行分區,增加了復雜性,會有一定性能的消耗,通俗的講就是你select的語句消耗的時間很短,要小於多線程之間頻繁切換的時間。
PLINQ 四種分區方式
1、范圍分區:對輸入的元素根據處理器核數對元素進行平分,元素為實現了IList<T>接口的類型。
2、區塊分區:每個線程使用一塊區域內的一定數量的元素,區塊大小不固定,執行過程中,會動態的進行調整,原則是盡可能保證所有任務同時完成。
3、條帶分區:跳過n個元素,處理m個元素,處理完成后跳過n個元素,執行m個元素
4、散列分區:。。。。。。沒理解,只知道同3一樣是對特定的查詢進行優化。
並行執行的算法:管道,停止並運行,反向枚舉三種算法。
管道:創建處理器核數+1個線程,一個枚舉線程記錄狀態,其他執行操作
停止並運行:ToList,ToArray等需要完整結果的的操作時使用該方法,但將占用更多的內存
反向枚舉:使用AsParallel方法后,調用ForAll方法
PLINQ的並行不是絕對的,下面的列表介紹了 PLINQ 默認情況下將按順序模式執行的查詢形狀:
-
包含 Select 子句、已建立索引的 Where 子句、已建立索引的 SelectMany 子句或 ElementAt 子句的查詢(在排序或篩選運算符移除或重新排列了索引后)。
-
包含 Take、TakeWhile、Skip、SkipWhile 運算符並且源序列中的索引未采用原始順序的查詢。
-
包含zip或SequenceEquals的查詢,除非,其中一個數據源具有原始順序排列的索引和其他數據源可建立索引(IE.. 數組或ilist(t))。
-
包含 Concat 的查詢,除非將其應用到可建立索引的數據源。
-
包含 Reverse 的查詢,除非應用到可建立索引的數據源。
提到過AsParallel方法返回的是ParallelEnumerable,下面列出ParallelEnumerable中幾個方法,是我們更加靈活的使用PLINQ(PD:雖然公司里應該不會用到~)。
AsOrdered和AsUnordered方法,告訴PLINQ結果序列中順序是否(看的比錢)重要。
AsSequential:強制順序執行。
AsExecutionMode:強制並行執行。
WithDegreeOfParallelism:指定並行時最大的線程數。
WithMergeOptions:設置PLNQ執行時的緩存類型,建議使用默認模式AutoBuffered。
沒有貼多少代碼,估計自己以后看都懶的看了,因為我沒有從頭到尾的敲下來,在圖書館幾點知識點回來結合網絡就這么整理一下,那么怎么才能用到PLINQ(在代碼中查找類似循環能被並行執行的代碼,嘗試轉為並行)。