首先,產生五千萬筆0~10000亂數資料。
//產生測試資料
List testData = new List();
Random Rand = new Random();
//產生亂數字串
for (int i = 0; i < 50000000; i++)
{
testData.Add(Rand.Next(0, 10000));
}
首先,產生五千萬筆0~10000亂數資料。
//產生測試資料
List< int > testData = new List< int >();
Random Rand = new Random();
//產生亂數字串
for (int i = 0; i < 50000000; i++)
{
testData.Add(Rand.Next(0, 10000));
}
先用一般的foreach方式跑,平均時間約1.2秒。
List< int > resultData = new List< int >();
foreach (var item in testData)
{
if (item.Equals(55) || item.Equals(99))
{
resultData.Add(item);
}
}
用4.0的平行運算方式跑,平均時間約1秒左右...
ConcurrentStack< int > resultData2 = new ConcurrentStack< int >();
Parallel.ForEach(testData, (item, loopState) =>
{
if (item.Equals(55) || item.Equals(99))
{
resultData2.Push(item);
}
});
之前單純不加判斷式,只將資料放入集合中,會因為資源等候問題導致處理處理更慢,如果是應用在大量的程式判斷上,效能提升就可以看得出來了。
此範例如果改成0~100的亂數,又會因為資源等候造成比較慢,所以使用時機還是需要慎重考慮。
引用黃忠成老師的一段話:
當你針對TPL來測定效能的提升度時,有時會落入一個數字的迷思,最常見的是當效能總數降到1000 ms以下時,不管你如何做,效能的提升都很有限,這是因為For、ForEach本身也是需要建立成本的,當建立成本高於單緒執行成本時,你就應該考慮該工作是否適合使用TPL。
偶而,你會觀測到懸殊的差距,這多半是因為TPL分割資料時發生無法整除於核心數時,其會多加一個Task,也就是說4核的電腦上,是有可能出現For、ForEach產生5個Task執行的情況,此時如果要搜尋的資料元素是在陣列的尾端時,因為第5個Task的出現,所以會很快就找到。
感謝這段話讓我對平行運算的觀念更清楚了。
參考來源:http://www.dotblogs.com.tw/asdtey/archive/2010/05/08/parallelforforeach.aspx
http://www.dotblogs.com.tw/code6421/archive/2010/02/25/13770.aspx