LoginSignup
8
8

More than 5 years have passed since last update.

ParallelQuery の列挙には foreach ではなく ForAll() を使いましょう

Posted at

目的

1回1回の処理が重い列挙を速くしたい。

こんなの。

var source = Enumerable.Range(0, 20);

var sw = Stopwatch.StartNew();
foreach (var i in source) {
    Fetch(i);
}
Console.WriteLine(sw.Elapsed);
// 00:00:02.0102643

void Fetch(int number) {
    // 重い処理。
    Thread.Sleep(100);
}

並列実行したら速そう。

AsParallel() を付ける

foreach (var i in source.AsParallel()) {
    Fetch(i);
}
Console.WriteLine(sw.Elapsed);
// 00:00:02.0139477

あれ、遅い・・・

foreach → ForAll() で列挙

source.AsParallel().ForAll(i => {
    Fetch(i);
});
Console.WriteLine(sw.Elapsed);
// 00:00:00.5032450

(サラマンダーより)速い!

Parallel.ForEach() も試してみる。

Parallel.ForEach(source, i => {
    Fetch(i);
});
Console.WriteLine(sw.Elapsed);
// 00:00:00.5017158

速い!

比較

BenchmarkDotNet はマルチスレッドのベンチマーク向けにデザインされていないけど、一応貼っておく。


BenchmarkDotNet=v0.10.14, OS=Windows 10.0.14393.2068 (1607/AnniversaryUpdate/Redstone1)
Intel Core i5-6200U CPU 2.30GHz (Skylake), 1 CPU, 4 logical and 2 physical cores
Frequency=2343751 Hz, Resolution=426.6665 ns, Timer=TSC
.NET Core SDK=2.1.104
  [Host] : .NET Core 2.0.6 (CoreCLR 4.6.26212.01, CoreFX 4.6.26212.01), 64bit RyuJIT
  Core   : .NET Core 2.0.6 (CoreCLR 4.6.26212.01, CoreFX 4.6.26212.01), 64bit RyuJIT

Job=Core  Runtime=Core  

Method Mean Error StdDev Median Min Max Scaled ScaledSD Gen 0 Allocated
Enumerable_foreach 36.781 ms 0.7284 ms 0.6457 ms 36.771 ms 35.680 ms 37.995 ms 1.00 0.00 - 0 B
ParallelQuery_foreach 36.969 ms 0.6525 ms 0.6104 ms 36.757 ms 35.833 ms 38.051 ms 1.01 0.02 - 0 B
ParallelQuery_ForAll 9.753 ms 0.0826 ms 0.0848 ms 9.764 ms 9.579 ms 9.885 ms 0.27 0.01 - 3808 B
Parallel_ForEach 2.975 ms 0.3545 ms 1.0453 ms 2.503 ms 1.974 ms 5.392 ms 0.08 0.03 31.2500 5959 B

ParallelQuery_ForAll の Scaled が Enumerable_foreach(ベースライン)の 1/4 になっていて、4つの論理コアをいい感じに使っている(Parallel_ForEach はなんかアレだけど)。

ソースコード

総括

ParallelQuery を foreach で列挙しても foreach 自体は並列実行されない ので、列挙の並列化が必要な時は ForAll() を使いましょう。

参照

8
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8