这是方法返回任务的基准,但在后台同步运行。
class MainClass
{
public static async Task<int> UsingAsyncModifier()
{
return 10;
}
public static Task<int> UsingTaskCompletionSource()
{
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
tcs.SetResult(10);
return tcs.Task;
}
public static Task<int> UsingTaskFromResult()
{
return Task.FromResult(10);
}
public static void Main(string[] args)
{
DateTime t = DateTime.Now;
const int repeat = 10000; // Results volatile while repeat grows.
Console.WriteLine("Repeat {0} times.", repeat);
int j = 0;
for (int i = 0; i < repeat; i++)
{
j += UsingAsyncModifier().Result;
}
Console.WriteLine("UsingAsyncModifier: {0}", DateTime.Now - t);
t = DateTime.Now;
for (int i = 0; i < repeat; i++)
{
j += UsingTaskCompletionSource().Result;
}
Console.WriteLine("UsingTaskCompletionSource: {0}", DateTime.Now - t);
t = DateTime.Now;
for (int i = 0; i < repeat; i++)
{
j += UsingTaskFromResult().Result;
}
Console.WriteLine("UsingTaskFromResult: {0}", DateTime.Now - t);
}
}
Run Code Online (Sandbox Code Playgroud)
输出(重复 10,000/100,000/1000,000 次):
Repeat 10000 times.
UsingAsyncModifier: 00:00:00.1043980
UsingTaskCompletionSource: 00:00:00.0095270
UsingTaskFromResult: 00:00:00.0089460
Run Code Online (Sandbox Code Playgroud)
重复 10,000 次, UsingTaskFromResult 比UsingAsyncModifier快 10 倍。
Repeat 100000 times.
UsingAsyncModifier: 00:00:00.1676000
UsingTaskCompletionSource: 00:00:00.0872020
UsingTaskFromResult: 00:00:00.0870180
Run Code Online (Sandbox Code Playgroud)
重复 100,000 次, UsingTaskFromResult 比UsingAsyncModifier快 2倍。
Repeat 1000000 times.
UsingAsyncModifier: 00:00:00.8458490
UsingTaskCompletionSource: 00:00:00.8870980
UsingTaskFromResult: 00:00:00.9027320
Run Code Online (Sandbox Code Playgroud)
重复 1,000,000 次,UsingAsyncModifier比 UsingTaskFromResult 略快。
我的想法是,async修改器刚刚创建了一个已完成的任务,就像Task.FromResult()这样。但基准并不能证明我的想法。为什么?
虽然我使用 看到了类似的结果DateTime,但使用Stopwatch进行时间测量表明,即使进行 1 000 000 次迭代 ,使用 的迭代UsingAsyncModifier()也会花费 2 倍多的持续时间(比使用UsingTaskCompletionSource()或UsingTaskFromResult(),两者都显示相同的近似持续时间)
这是输出:
Repeat 1000000 times.
UsingAsyncModifier: 5458
UsingTaskCompletionSource: 2838
UsingTaskFromResult: 2556
Run Code Online (Sandbox Code Playgroud)
与你的代码使用Stopwatch
class Program
{
public static async Task<int> UsingAsyncModifier()
{
return 10;
}
public static Task<int> UsingTaskCompletionSource()
{
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
tcs.SetResult(10);
return tcs.Task;
}
public static Task<int> UsingTaskFromResult()
{
return TaskEx.FromResult(10);
}
static void Main(string[] args)
{
//DateTime t = DateTime.Now;
Stopwatch timer = new Stopwatch();
const int repeat = 1000*1000; // Results volatile while repeat grows.
Console.WriteLine("Repeat {0} times.", repeat);
int j = 0;
//DateTime t = DateTime.Now;
timer.Start();
for (int i = 0; i < repeat; i++)
{
j += UsingAsyncModifier().Result;
}
timer.Stop();
Console.WriteLine("UsingAsyncModifier: {0}"
, timer.ElapsedMilliseconds);
//t = DateTime.Now;
timer.Reset();
j = 0;
timer.Start();
for (int i = 0; i < repeat; i++)
{
j += UsingTaskCompletionSource().Result;
}
timer.Stop();
Console.WriteLine("UsingTaskCompletionSource: {0}"
, timer.ElapsedMilliseconds);
//t = DateTime.Now;
timer.Reset();
j = 0;
timer.Start();
for (int i = 0; i < repeat; i++)
{
j += UsingTaskFromResult().Result;
}
timer.Stop();
Console.WriteLine("UsingTaskFromResult: {0}"
, timer.ElapsedMilliseconds);
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
Stephen Toub 在他的“异步性能:了解异步和等待的成本”中解释道:
使用同步代码时,具有空主体的方法实际上是免费的。异步方法并非如此
阅读更多详细信息