TPL - запросы PLINQ упорядочены по умолчанию? - PullRequest
0 голосов
/ 22 июня 2011

В нескольких подкастах, которые я слушал, чтобы обсудить PLINQ, исходная идея заключалась в том, чтобы по умолчанию предоставлять неупорядоченные запросы по причинам производительности, и разработчик мог решить сделать его упорядоченным, если это было важно. Но затем было заявлено, что это будет изменено на порядок по умолчанию, и разработчики, которые хотят дополнительной производительности и не заботятся о порядке, могут сделать его неупорядоченным.

Все примеры и документы, которые я видел, используют .AsOrdered (), что наводит меня на мысль, что он по-прежнему неупорядочен по умолчанию.

Может кто-нибудь пролить свет на это?

Ответы [ 2 ]

1 голос
/ 22 июня 2011

PLINQ не закажет ваши результаты, если вы не укажете AsOrdered. Поскольку Parallel LINQ будет выполнять работу одновременно, он может завершить второй элемент до первого.

Скажем, у вас есть класс, который выглядит так:

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

Допустим, Bar в разных случаях Foo занимает неопределенное количество времени для завершения, потому что он проверяет файл. Допустим, у нас есть случай, когда элементу Bar требуется 10 секунд для завершения, а элементу Б - 1. Поскольку B закончил первым, он оказался сверху.

.NET не будет заказывать его по умолчанию, потому что он должен завершить элементы по порядку, прежде чем перейти к следующему. Вы не можете заказать то, что вы не знаете. Поэтому по соображениям производительности они неупорядочены по умолчанию. AsOrdered указывает, что заказ важен, но за счет блокировки.

1 голос
/ 22 июня 2011

По умолчанию они абсолютно неупорядочены, и именно поэтому существует AsOrdered. Использование AsOrdered вводит дополнительный шаг и, следовательно, дополнительные издержки, чтобы получить результаты из разрозненных рабочих потоков и привести их в надлежащий порядок. Кроме того, если это не очевидно, AsOrdered блокирует (см. Обновление ниже), что означает, что результаты не будут проходить через конвейер запросов PLINQ, пока элементы не поступят в том порядке, в котором они изначально были запущены.

Наконец, обратите внимание, что существует AsUnordered, так что вы можете переключить запрос обратно на неупорядоченный запрос с этой точки вперед в конвейере запросов.

UPDATE:

Я просто хочу уточнить, что я имею в виду под "блокировкой". Что происходит, так это то, что PLINQ должен соблюдать исходный порядок элементов в тот момент, когда они передаются в ParallelQuery. Оттуда он будет гарантировать, что элементы, завершившиеся до элементов, вышедших из строя, будут буферизованы . Поэтому, если у вас есть элементы в таком порядке, как «один», «два», «три» и «два» заканчиваются до «одного», «два» будут буферизироваться до тех пор, пока «один» не будет завершен.

...