Параллельный.ForEach медленнее, чем ForEach

Вот код:

using (var context = new AventureWorksDataContext()) { IEnumerable _customerQuery = from c in context.Customers where c.FirstName.StartsWith("A") select c; var watch = new Stopwatch(); watch.Start(); var result = Parallel.ForEach(_customerQuery, c => Console.WriteLine(c.FirstName)); watch.Stop(); Debug.WriteLine(watch.ElapsedMilliseconds); watch = new Stopwatch(); watch.Start(); foreach (var customer in _customerQuery) { Console.WriteLine(customer.FirstName); } watch.Stop(); Debug.WriteLine(watch.ElapsedMilliseconds); } 

Проблема в том, что Parallel.ForEach занимает около 400 мс против обычного foreach , что занимает около 40 мс. Что именно я делаю неправильно и почему это не работает, как я ожидаю?

Предположим, у вас есть задача выполнить. Предположим, вы учитель математики, и у вас есть двадцать бумаг для оценки. У вас есть две минуты, чтобы оценить бумагу, так что вам понадобится около сорока минут.

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

Теперь предположим, что у вас есть двадцать тысяч бумаг для оценки, так что это займет около 40000 минут. Теперь, если вы потратите час на поиски помощников, это победа. Каждый из вас принимает 4000 документов и составляет в общей сложности 8060 минут вместо 40000 минут, экономия почти в 5 раз. Накладные расходы на поиск помощников в основном неактуальны.

Параллелизация не является бесплатной . Стоимость разделения работы между различными streamами должна быть крошечной по сравнению с объемом работы, выполняемой в streamе.

Дальнейшее чтение:

https://en.wikipedia.org/wiki/Amdahl%27s_law

https://en.wikipedia.org/wiki/Gustafson%27s_law

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

Дополнительные накладные расходы на создание всех streamов для вашего перечисляемого VS, просто выполняющего счетчик, более чем вероятно являются причиной замедления. Parallel.ForEach – это не полный рост производительности; необходимо взвешивать, может ли быть выполнена операция, которая должна быть завершена для каждого элемента.

Например, если вы хотите сделать веб-запрос или что-то вместо простого написания на консоль, параллельная версия может быть быстрее. Как бы то ни было, просто написать на консоль очень быструю операцию, поэтому накладные расходы на создание streamов и их запуск будут медленнее.

Как сказал предыдущий автор, некоторые издержки связаны с Parallel.ForEach , но это не значит, что вы не видите улучшения своей производительности. Console.WriteLine – это синхронная операция, поэтому только один stream работает одновременно. Попытайтесь сменить тело на что-то неблокирующее, и вы увидите увеличение производительности (пока объем работы в теле достаточно велик, чтобы уменьшить лишние расходы).

  • Как связать List с элементом управления DataGridView?
  • Я работаю как служба
  • Преобразование строки в DateTime
  • Добавление неизвестных (во время разработки) свойств в ExpandoObject
  • Что такое синтаксис инициализации структуры тегов?
  • Почему компиляторы C не могут изменять элементы структуры для исключения выравнивания?
  • Добавить привилегию «Все» в папку с помощью C # .NET
  • Количество файлов из папки
  • Как я могу отражать элементы динамического объекта?
  • Профилирование процесса компиляции C ++
  • Компилятор Linux C
  • Давайте будем гением компьютера.