Странно медленно: что случилось, когда TakeWhile встретил AsParallel?
Я знаю, что неправильное использование linq может привести к снижению производительности, но на этот раз это слишком странно.
Когда я вызываю "AsParallel.TakeWhile.AsParallel.ForAll", это НАМНОГО медленнее, чем "AsParallel.TakeWhile.ForAll". Может кто-нибудь объяснить, почему?
using System;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Action<int> doNothing = i => { };
var stopwatch = Stopwatch.StartNew();
Enumerable.Range(1, 100).AsParallel().TakeWhile(m => m < 10)
.ForAll(doNothing);
var ticks1 = stopwatch.ElapsedTicks;
stopwatch.Restart();
Enumerable.Range(1, 100).AsParallel().TakeWhile(m => m < 10)
.AsParallel() // spend much more time with this AsParallel
.ForAll(doNothing);
var ticks2 = stopwatch.ElapsedTicks;
Console.WriteLine("ticks without AsParallel: {0}\r\n with AsParallel: {1}", ticks1, ticks2);
//ticks without AsParallel: 87956
//with AsParallel: 6688708
Console.Read();
}
}
}
1 ответ
Когда вы вызываете AsParallel, среда начинает делить работу на более мелкие части, которые можно запланировать на разных ядрах. Эти части позже нужно было объединить обратно в результат. Это вызывает некоторые накладные расходы.
Вы уже сделали запрос параллельным с помощью первого "AsParallel", и когда вы вызываете его во второй раз, раздел происходит снова, вызывая еще больше накладных расходов, но не давая вам повышения производительности.
Посмотрите Понимание Ускорения в PLINQ для получения дополнительной информации.