2011-06-22 62 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表示订单很重要,但是以阻止为代价。