В .NET Framework 4.0 планируется (и в Beta 1 уже есть) некоторая поддержка параллельных вычислений. Что, конечно, не может не радовать в свете того, что я уже писал здесь по поводу многопроцессорности, многоядерности и человеческих способностей всё это эффективно использовать.
В частности, в .NET 4.0 появляются такие вещи, как статический класс Parallel:
Parallel.For()
Parallel.For<>()
Parallel.ForEach<>()
Parallel.Invoke()
и статический класс ParallelEnumerable со всеми его благами в виде .Cast<>, .All, .Where, .GroupBy и прочее, прочее.
Кроме того, IEnumetable теперь тоже имеет метод-расширение (или как это по-русски? придумали термин? extension method, в общем) .AsParallel, позволяющий распараллелить операции над элементами последовательности.
Очень здорово: если у меня есть цикл, обрабатывающий немереное количество данных и я знаю, что обработка каждого элемента независима (например, я увеличиваю стоимость каждого продукта на 20% и выбираю все, ценою до 50 долларов), то все, что мне нужно сделать, чтобы эта часть приложения работала эффективнее – это просто воспользоваться соответствующей конструкцией.
Насколько оно эффективно?
Ну, если верить словам разработчикам pLINQ (parallel LINQ), выступление которых я смотрел еще на TechEd 2008 Australia, то достаточно эффективно: “параллелит” оно учитывая количество процессоров/ядер, данные, что-то еще… Плюс там предусмотрено несколько стратегий работы (как именно парраллелить данные), используются lock-free алгоритмы… Словом, это гораздо, гораздо эффективнее того, что делает большинство из нас даже в лучшем случае (создать 1-2 потока на ядро). В обычном же (даже не в худжем) случае мы даже не думаем о параллельности, просто пуская привычный for/foreach, правда?
Ну, и эксперимент. Простой цикл на 1000 итераций, я не придумал, что делать в каждой из итераций, поэтому просто сделал там задержку в 100 милисекунд.
Результат:
Первая цифра - “обычный” for, вторая - Parallel.For().