私はいくつかの同期コードに同時実行性を追加したいと思って、理解しにくいプロセスでパフォーマンスの問題を発見しました。Task.WaitAll()と実行Task.Waitのパフォーマンスのギャップの問題
以下のコードの実行結果は、次のとおり
Mission Fibonacci1Async cost 9.4195388 seconds, value 75025
Mission Fibonacci2Async cost 0.2260129 seconds, value 75025
異なるのみ2RD機能はラインを添加するTask.WhenAll(新しいタスク[] {T1、T2を})待ちます。の場合、パフォーマンスを40倍向上させます。
誰でも私に説明できますか?
static Task<int> Fibonacci1Async(int n)
{
return Task.Run<int>(() => Fibonacci1(n));
}
static int Fibonacci1(int n)
{
if (n == 0) return 0;
else if (n == 1) return 1;
else
{
var t1 = Fibonacci1Async(n - 1);
var t2 = Fibonacci1Async(n - 2);
return t1.Result + t2.Result;
}
}
static Task<int> Fibonacci2Async(int n)
{
return Task.Run<int>(() => Fibonacci2(n));
}
static int Fibonacci2(int n)
{
if (n == 0) return 0;
else if (n == 1) return 1;
else
{
var t1 = Fibonacci2Async(n - 1);
var t2 = Fibonacci2Async(n - 2);
Task.WaitAll(new Task[] { t1, t2 });
return t1.Result + t2.Result;
}
}
static void Benchmark(Func<int, Task<int>> func)
{
DateTime time = DateTime.Now;
var task = func(25);
task.Wait();
TimeSpan cost = DateTime.Now - time;
Console.WriteLine("Mission {0} cost {1} seconds value {2}", func.Method.Name, cost.TotalSeconds, task.Result);
}
static void Main(string[] args)
{
Benchmark(Fibonacci1Async);
Benchmark(Fibonacci2Async);
Console.ReadKey();
return;
}
命名規則は、await/asyncとは関係ありません。これは実装の詳細です。これは、呼び出し側がタスクを受け取り、非ブロック動作を取得することを指定します。 – usr
ポスト 'Async'と戻り値の型を組み合わせると、メソッドはタスクベースの非同期パターンを使用します。これらの '* Async'メソッドがTAPであるケースを作ることができると思いますが、確かにTAP実装の良い例ではありません。 –
FileStream.ReadAsyncは、内部的にawaitを使用しません。 IO完了ポートを使用します。何も間違っていません。発信者は知る必要はありません。 – usr