你的「問題」是使用PLINQ時,它沒有任何意義
PLINQ不會總是更快。 PLINQ將永遠增加開銷。
就CPU指令而言;無論您需要做多少工作(稱之爲X),您最終都會執行超過X條指令。 PLINQ將開展大量額外的工作,將工作委託給他們,並將結果返回到您可以使用的表單中。
這樣做的好處是你可以有多個CPU/Core的工作。有時它會更快。當你所做的CPU工作量相對於開銷很小時,它會變慢。
當我運行代碼,我得到以下的輸出:
順序執行2毫秒
並行執行40毫秒
我還可以看到正在創建工作線程由PLINQ代碼。這8個線程代表了2毫秒計算量的大量開銷。通過兩次運行「並行執行」基準測試,您可以感覺到它有多少開銷。工作線程將會四處流動。這是我的輸出與運行它的第二時間:
順序執行2毫秒
並行#1執行40毫秒
並行#2執行3毫秒
第二時間是快多了;但仍然比不做任何事情慢。因爲即使已經創建了工作線程 - PLINQ仍然需要做工作來分割線程之間的操作並以可以訪問的格式重新獲得結果。
您需要做的工作越多,對開銷的影響就越小。在這個例子中,我用一個名爲IsValid
的靜態函數替換了你的Where lambda,並且我計算了%2 500次而不是一次。
static bool IsValid(int input)
{
int result=0;
for(int i =0;i<500;i++)
result = input%2;
return result == 0;
}
現在 - 我的執行時間是:
順序執行36毫秒
並行#1執行47毫秒
並行#2執行9毫秒
你可以看到PLINQ仍然很慢第一次執行 - 但在第二次執行時速度明顯加快。如果通過將環路從500增加到5000(在我的機器上)來實現CPU工作,PLINQ將勝出,而不用擔心。
TL; DR - 你做得對;你只是沒有做足夠的工作來讓PLINQ成爲更快的選擇。
下面是我做了什麼,整個源代碼:
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
int[] vals = Enumerable.Range(0, Int16.MaxValue).ToArray();
sw.Start();
int[] x1 = vals.Where(IsValid).ToArray();
sw.Stop();
Console.WriteLine("Sequential Execution {0} milliseconds", sw.ElapsedMilliseconds);
sw.Restart();
int[] x2 = vals.AsParallel().Where(IsValid).ToArray();
sw.Stop();
Console.WriteLine("Parallel #1 Execution {0} milliseconds", sw.ElapsedMilliseconds);
sw.Restart();
int[] x3 = vals.AsParallel().Where(IsValid).ToArray();
sw.Stop();
Console.WriteLine("Parallel #2 Execution {0} milliseconds", sw.ElapsedMilliseconds);
Console.Read();
}
static bool IsValid(int input)
{
int result=0;
for(int i =0;i<5000;i++)
result = input%2;
return result == 0;
}
http://stackoverflow.com/questions/7582591/how-to-plinq-an-existing-linq-query-with-加入(閱讀我的推薦讀物)。簡而言之:你的模操作太微不足道了。你需要更復雜的操作。 –