这里有一个方法返回任务的基准测试,但在内部是同步运行的。
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);
}
}
输出(重复10,000/100,000/1,000,000次):
Repeat 10000 times.
UsingAsyncModifier: 00:00:00.1043980
UsingTaskCompletionSource: 00:00:00.0095270
UsingTaskFromResult: 00:00:00.0089460
重复10,000次,UsingTaskFromResult
比 UsingAsyncModifier 快10倍。
Repeat 100000 times.
UsingAsyncModifier: 00:00:00.1676000
UsingTaskCompletionSource: 00:00:00.0872020
UsingTaskFromResult: 00:00:00.0870180
重复操作 100,000 次,UsingTaskFromResult 比 UsingAsyncModifier 更快 2 倍。
Repeat 1000000 times.
UsingAsyncModifier: 00:00:00.8458490
UsingTaskCompletionSource: 00:00:00.8870980
UsingTaskFromResult: 00:00:00.9027320
重复1,000,000次,使用AsyncModifier比使用TaskFromResult稍微快一点。
我的想法是,async
修饰符只是创建了一个已完成的任务,类似于Task.FromResult()
。但是基准测试并没有证明我的想法。为什么?
DateTime.Now
实际上没有足够的精度来测量如此短的时间。对于执行如此快速的基准测试代码片段,非常困难。实际上,你的测试并没有传达任何有意义的信息;误差范围非常高,结果实际上毫无意义。 - ServyDispatcher
类中,后台作业运行得非常快,以至于在异步请求返回之前,它看起来已经完成了)。正如@Servy所建议的那样,在这些条件下,你的测试并不真正具有意义。 - Dan Puzeyawait
的异步方法会同步运行。但是,它不能在不返回任务来包装返回结果的情况下运行。我相信使用async
的人正确理解了我所写的,而不必费心思如何以更长的方式写得不太含糊。 - Gennady Vanin Геннадий Ванин