Параллельный linq


Download 19.51 Kb.
Sana01.03.2023
Hajmi19.51 Kb.
#1240282
TuriЛекции
Bog'liq
Омонов.Ш



Параллельный LINQ

Language-Integrated Query (LINQ) предоставляет декларативную модель, которая позволяет запрашивать последовательности данных, таких коллекции в памяти, документы XML и данные базы данных. Характер многих запросов означает, что их можно легко распараллелить. Большинство запросов выполняют одну и ту же группу действий для каждого элемента в коллекции. Если все эти действия являются независимыми, без побочных эффектов, вызванных порядком, в котором они появляются, вы часто можете добиться большого увеличения производительности за счет разделения работы между несколькими процессорными ядрами.


Чтобы поддержать эти сценарии .NET Framework версии представила Parallel LINQ (PLINQ). PLINQ предоставляет те же стандартные операторы запросов и синтаксис выражений запроса, что и LINQ. Основное различие заключается в том, что исходные данные могут быть разбиты на части с использованием декомпозиции данных. Эти меньшие группы данных затем потенциально обрабатываются всеми доступными ядрами ЦП. PLINQ имеет некоторые ограничения, которые означают, что он не является прямой заменой LINQ и не может быть параметром по умолчанию для запросов. Ключом к числу ограничений является то, что побочные эффекты обработки отдельных элементов из исходных последовательностей, такие как результат обработки одного элемента, зависящего от другого, могут приводить к непредсказуемым результатам. Это связано с тем, что исходные элементы обычно не обрабатываются в исходном порядке. Второе ограничение заключается в том, что PLINQ обеспечивает параллелизм для данных в памяти, таких как коллекции или предварительно загруженный XML.
Чтобы показать, как может быть изменен запрос LINQ для параллельной обработки, сначала нужна последовательная версия. В приведенном ниже коде показан очень простой запрос. Здесь мы начинаем с массива, содержащего целые числа от одного до десяти. Используя оператор Select, мы проецируем его на новую последовательность, содержащую квадраты исходных значений. Поскольку LINQ использует отложенное выполнение, новая последовательность не генерируется до тех пор, пока данные не будут доступны. Это означает, что цикл foreach заставляет запрос выполняться и выводит результаты.
int[] sequence = Enumerable.Range(1, 10).ToArray();
var squares = sequence.Select(x => x * x);
foreach (var square in squares)
{
Console.Write(square + " ");
}
Console.ReadLine();
Результат: 1 4 9 16 25 36 49 64 81 100
LINQ работает с последовательностями, реализующими интерфейс IEnumerable. Чтобы обозначить, что мы хотим использовать PLINQ, мы должны использовать статический метод AsParallel. Это метод расширения IEnumerable, поэтому его можно применять к любой последовательности, поддерживающей операции LINQ. Он возвращает объект
типа ParallelQuery . Когда у вас есть параллельная последовательность данных, вы можете использовать ее в качестве источника для операций LINQ,
как и в любой другой последовательности. PLINQ разлагает данные таким образом, чтобы обеспечить эффективную параллельную обработку.
Чтобы распараллелить запрос, добавьте вызов в AsParallel, как показано
ниже:
var squares = sequence.AsParallel().Select(x => x * x);
Результат: 100 1 25 36 49 64 81 4 9 16
Возможно, вы заметили, что результаты PLINQ запроса правильны, но они появились в другом порядке, чем при использовании последовательной версии LINQ. Это побочный продукт при параллельном выполнении запросов
LINQ. В некоторых случаях упорядочение результатов не имеет значения, особенно если данные впоследствии сортируются с использованием стандартного оператора запроса OrderBy или каким-либо императивным методом. В других случаях нарушения первоначального порядка может быть катастрофической. В таких ситуациях вам нужно сохранить упорядочение результатов в соответствии с порядком ввода. PLINQ поддерживает Сохранение порядка параллельного источника данных с использованием метода AsOrdered. Этот метод следует использовать только тогда, когда необходимо поддерживать порядок результатов, так как это может значительно снизить производительность ваших запросов.
Следующий запрос использует метод AsOrdered после AsParallel для
сохранения порядка результатов.
var squares = sequence.AsParallel().AsOrdered().Select(x => x * x);
Результат: 1 4 9 16 25 36 49 64 81 100

Когда вы выполняете последовательный запрос с использованием LINQ,


любой обработанный элемент данных может привести к исключению. Когда исключение брошено, запрос немедленно останавливается выполнение. С PLINQ возможно одновременное выполнение нескольких операций. Если одно из них выдает исключение, все остальные потоки останавливаются, но только после завершения запланированных операций. Это может означать задержку между исключительным событием и остановкой запроса PLINQ, если операции запроса медленны. Это также означает, что любая из других параллельных операций может также генерировать исключение. Чтобы устранить возможность запроса, вызывающего множественные исключения, все исключения из запроса PLINQ объединяются в одно исключение AggregateException, которое бросается, выполнения останавливаются. Как и при использовании параллельных циклов и задач, вы можете перехватить это исключения его свойство InnerExceptions, чтобы найти все исключения.

Download 19.51 Kb.

Do'stlaringiz bilan baham:




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling