2011-06-22 60 views
0

在我聽到討論PLINQ的幾個播客中,最初的想法是默認提供無序查詢以滿足性能方面的原因,如果這很重要,開發人員可以決定對其進行排序。但後來有人表示,這將被改爲默認排序,想要額外表現並且不關心訂單的開發者可能會使其無序。TPL - 是否默認命令PLINQ查詢?

我見過的所有示例和文檔都使用.AsOrdered(),這導致我相信它仍然是默認無序的。

有人可以對此有所瞭解嗎?

回答

1

他們絕對是無序的,這正是爲什麼AsOrdered存在。使用AsOrdered引入了一個額外的步驟,並因此額外開銷,從不同的工作線程中獲取結果並使其處於正確的順序。此外,如果不是很明顯,AsOrdered阻止(參見下面的更新),這意味着結果將不通過PLINQ查詢管道進度,直至項目在他們原來的啓動順序已經到達。

最後,注意AsUnordered的存在使得您可以在查詢管道中將該查詢從該點向前切換回無序查詢。

UPDATE:

我只是想澄清我所說的 「堵」 的意思。發生什麼事是PLINQ必須在交給ParallelQuery時觀察元素的原始順序。從那裏它將確保元素在元素無序之前完成緩衝。所以如果你在「one」之前有「one」,「two」,「three」和「two」等順序的元素,那麼「two」將會被緩衝,直到「one」完成。

+0

謝謝,我不知道阻塞的方面。你知道他們爲什麼沒有默認它下令嗎? –

+0

因爲在一個平行的世界中,你希望儘可能少的不同數據元素之間的耦合。一旦你說你需要訂單,這意味着元素是以某種方式相關的。所以他們默認無序地滿足大多數並行程序員的期望,並將AsOrdered添加爲明確要求那些真正需要它的人。 –

+0

@DustinDavis因爲它傷害了表現。對於性能很重要的東西(如PLINQ),這與它的目的相反。在很多情況下,訂單並不重要。如果是,*然後*招致表演。 – vcsjones

1

除非您指定AsOrdered,否則PLINQ不會訂購您的結果。由於並行LINQ將同時執行工作,因此它可能會在第一個項目之前完成第二個項目。

假設你有一個類,看起來像這樣:

public class Foo 
{ 
    public int Bar() {return something;} 
} 

假設Bar上的Foo不同情況下采取的一個不確定的時間才能完成,因爲它會檢查文件。所以說我們有一個情況,其中項目A的Bar需要10秒才能完成,但項目B的需要1個。由於B首先完成,它將在最上面結束。

.NET在默認情況下不會對它進行排序,因爲它需要先完成項目才能繼續下一個項目。你不能訂購你不知道的東西。所以出於性能原因,它們默認是無序的。 AsOrdered表示訂單很重要,但是以阻止爲代價。