TPL - PLINQ 查询默认排序吗?
在我听过的一些播客中讨论 PLINQ 时,最初的想法是出于性能原因默认提供无序查询,如果这很重要,开发人员可以决定将其排序。但随后有人表示,这将被更改为默认排序,想要额外性能且不关心顺序的开发人员可以将其设为无序。
我见过的所有示例和文档都使用 .AsOrdered() 这让我相信它默认情况下仍然是无序的。
有人可以解释一下吗?
In a few podcasts I listened to discussing PLINQ, the original idea was to provide unordered queries by default for perfromance reasons and the dev could decide to make it ordered if that was important. But then it was stated that this was going to be changed to be ordered by default and devs who wanted extra performance and didn't care about order could make it unordered.
All examples and docs i've seen use .AsOrdered() which leads me to believe that it's unordered by default still.
Can someone shed some light on this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
默认情况下它们是绝对无序的,这正是
AsOrdered
存在的原因。使用 AsOrdered 会引入额外的步骤,从而产生额外的开销,以从不同的工作线程中获取结果并使它们按正确的顺序排列。另外,如果不明显的话,AsOrdered
会阻塞(请参阅下面的更新),这意味着在项目按照最初开始的顺序到达之前,结果不会通过 PLINQ 查询管道进行。最后,请注意 < code>AsUnordered 存在,以便您可以从查询管道中的该点开始将查询切换回无序查询。
更新:
我只是想澄清一下“阻止”的含义。发生的情况是,当元素被传递给 ParallelQuery 时,PLINQ 必须观察元素的原始顺序。从那里它将确保在无序元素之前完成的元素被缓冲。因此,如果元素按“一”、“二”、“三”和“二”的顺序在“一”之前完成,则“二”将被缓冲,直到“一”完成。
They are absolutely unordered by default and that's exactly why
AsOrdered
exists. UsingAsOrdered
introduces an extra-step and, thus, extra-overhead, to take the results from the disparate worker threads and get them into proper order. Also, if it's not obvious,AsOrdered
is blocking (see update below) which means results will not progress through the PLINQ query pipeline until items have arrived in the order they original started in.Finally, note that
AsUnordered
exists so that you can switch the query back to a non-ordered query from that point forward in the query pipeline.UPDATE:
I just want to clarify what I mean by "blocking". What happens is that PLINQ has to observe the original order of the elements at the point when they are handed to the ParallelQuery. From there it will ensure that elements that complete before elements out of order are buffered. So if you have elements in order like "one", "two", "three" and "two" finishes before "one", "two" will be buffered until "one" is completed.
除非您指定
AsOrdered
,PLINQ 不会对您的结果进行排序。由于并行 LINQ 将同时执行工作,因此它可能会在第一项之前完成第二项。假设您有一个如下所示的类:
假设
Foo
的不同实例上的Bar
需要不确定的时间才能完成,因为它检查文件。假设我们有这样一种情况,项目 A 的Bar
需要 10 秒才能完成,但项目 B 需要 1 秒。由于 B 先完成,所以它最终位于顶部。默认情况下,.NET 不会对其进行排序,因为它需要按顺序完成项目,然后才能继续进行下一项。你不能订购你不知道的东西。因此出于性能原因,它们默认是无序的。
AsOrdered
表示顺序很重要,但代价是阻塞。PLINQ will not order your results unless you specify
AsOrdered
. Since Parallel LINQ will execute work concurrently, it may finish the second item before the first.Say you have a class that looks like this:
Let's say
Bar
on different instances ofFoo
takes an indeterminate amount of time to complete because it checks a file. So say we have a case where item A'sBar
takes 10 seconds to complete, but item B's takes 1. Since B finished first, it ends up on top..NET won't order it by default because it needs to complete items in order before moving on to the next one. You can't order what you don't know. So for performance reasons, they are unordered by default.
AsOrdered
indicates order is important, but at the cost of blocking.