導入
async/await は「待ち時間を無駄にしない(I/Oバウンド向き)」しくみでした。一方、**「重い計算を複数のCPUコアで同時にこなす(CPUバウンド向き)」**には Parallel や PLINQ を使います。ブラウザ内ランナーは単一スレッドのため、ここではコード例で読みます。
説明
flowchart TB
W["大量の重い計算"] --> P["Parallel.ForEach / AsParallel"]
P --> C1["コア1"]
P --> C2["コア2"]
P --> C3["コア3"]
style P fill:#fff3e0
サンプル
// Parallel.ForEach: 各要素の処理を複数コアに割り振る
var files = new[] { "a.txt", "b.txt", "c.txt" };
Parallel.ForEach(files, file =>
{
// 重い処理(画像変換・集計など)を各コアで並行に
Console.WriteLine($"処理中: {file}");
});
// PLINQ: LINQ に .AsParallel() を付けるだけで並列化
int[] numbers = Enumerable.Range(1, 1_000_000).ToArray();
long total = numbers.AsParallel().Where(n => n % 2 == 0).Sum(n => (long)n);
Console.WriteLine(total);
Parallel.For/Parallel.ForEachは繰り返しを複数コアに分散する- PLINQ(
AsParallel())は LINQ クエリを並列実行する - 向いているのはCPUバウンド(重い計算)。I/O待ちには
async/awaitを使う - 並列では共有状態の書き換えが危険(スレッド安全に注意。
lock/Interlocked/Concurrentコレクション) - 数が少なかったり1件が軽すぎると、分散の管理コストで逆に遅くなることもある
演習
手元で Enumerable.Range(1, 20_000_000) を、.Sum() と .AsParallel().Sum() の両方で Stopwatch を使って時間を比べてみましょう。並列化が効く規模感を体で覚えられます。
まとめ
Parallel/ PLINQ は重い計算を複数コアで同時にこなす(CPUバウンド向き)- I/O待ちは
async/await、重い計算は並列、と使い分ける - 共有状態の書き換えはスレッド安全に注意する
次回: JSONを実務レベルで制御する System.Text.Json です。