所以話題就是問題。AsParallel擴展實際上如何工作
我得到的方法AsParallel返回包裝ParallelQuery<TSource>
使用相同的LINQ的關鍵字,但是從System.Linq.ParallelEnumerable
代替System.Linq.Enumerable
這是很清楚的,但是當我尋找到反編譯的來源,我不明白怎麼做有用。
讓我們從最簡單的擴展開始:Sum()方法。代碼:
[__DynamicallyInvokable]
public static int Sum(this ParallelQuery<int> source)
{
if (source == null)
throw new ArgumentNullException("source");
else
return new IntSumAggregationOperator((IEnumerable<int>) source).Aggregate();
}
很明顯,我們來看看Aggregate()
的方法。它是InternalAggregate方法的一個封裝,用於捕獲一些異常。現在我們來看看它。
protected override int InternalAggregate(ref Exception singularExceptionToThrow)
{
using (IEnumerator<int> enumerator = this.GetEnumerator(new ParallelMergeOptions?(ParallelMergeOptions.FullyBuffered), true))
{
int num = 0;
while (enumerator.MoveNext())
checked { num += enumerator.Current; }
return num;
}
}
這裏是問題:它是如何工作的?我發現變量沒有併發安全性,被許多線程修改,我們只看到迭代器和求和。它是魔法枚舉器嗎?或者它是如何工作的? GetEnumerator()
返回QueryOpeningEnumerator<TOutput>
,但它的代碼太複雜了。
如果「這裏沒有多線程」,爲什麼sum2計算比sum1快3倍? http://i.imgur.com/Z4CtyUz.png –
@AlexJoukovsky:我測試了這個,'AsParallel'版本的確速度更快,但我不知道這怎麼可能,特別是因爲輸入枚舉也是在單個一次一個線程。離奇。 – Steven
部分和可以並行處理,然後合併。 – usr