你知道为什么同步fibonacci方法比async / await快,并且比异步任务更快?
我在每个项目方法上都使用了异步,所以主要是这个方法很糟糕......
码:
static int FibonacciSync(int number)
{
if (number == 0) { return 0; }
else if (number == 1) { return 1; }
else
{
var t1 = FibonacciSync(number - 1);
var t2 = FibonacciSync(number - 2);
return t1 + t2;
}
}
async static Task<int> FibonacciAwait(int number)
{
if (number == 0)
{ return 0; }
else if (number == 1)
{ return 1; }
else
{
var task1 = FibonacciAwait(number - 1);
var task2 = FibonacciAwait(number - 2);
return (await task1) + (await task2);
}
}
static Task<int> FibonacciAsync(int number)
{
if (number == 0)
{ return Task.FromResult(0); }
else if (number == 1)
{ return Task.FromResult(1); }
else
{
return FibonacciAsync(number - 1).ContinueWith(task1 =>
{
return FibonacciAsync(number - 2).ContinueWith(task2 =>
{
return task1.Result + task2.Result;
});
}).Unwrap();
}
}
结果:
你知道为什么同步fibonacci方法比async / await快,并且比异步任务更快?
异步不是为了提高原始速度。正如您所发现的那样,整体需要更长时间。如果你使用它很糟糕,就像你所做的那样,它会使事情变得更加缓慢,对于零利益而言要慢得多。
这里的根本问题是你不明白什么是异步。异步用于管理延迟。一旦你内化了这个事实,你就会开始正确使用它。
延迟是您请求计算或副作用以及计算或副作用完成之间的时间间隔。
例如,假设您正在计算计算成本极高的东西。例如,您正在计算一个非常复杂的图形,即使您将整个核心专用于它,计算也需要30毫秒以上的时间。在进行计算时,您不希望您的用户界面停止,因此您可以将计算放到另一个线程上,将CPU专用于该线程,然后等待结果。等待意味着“在等待高延迟操作完成时,找到更多工作要做”。
例如,假设您正在做一些计算成本不高但需要等待外部资源的事情。例如,您正在调用数据库,并且返回结果需要超过30毫秒。在这种情况下,您不想启动线程。那个线程正在等待结果睡觉!相反,您希望使用数据库访问API的异步版本,并等待高延迟结果。
在您的示例中,您没有开始的高延迟操作,因此等待它是没有意义的。你在那里所做的就是为运行时创建大量工作来创建和管理工作队列,这是你付出的工作但却没有从中受益。你的工作需要几纳秒;仅对占用毫秒或更长时间的作业使用异步。
只有在具有高延迟操作时才使用异步。 Async提高了性能,因为它可以释放一个线程,以便在等待高延迟结果出现时继续工作。如果没有高延迟的结果,那么异步只会减慢一切。
一个好的经验法则:只对使用外部资源的函数使用异步调用:文件系统,数据库,http调用,......
当你在内存中做的事情,比如计算fibonacci,做同步,在内存计算中创建一个单独的线程/上下文的开销太大了
除非你有一个等待计算结束的ui线程,你可以实现异步,但要注意你确实会有一些性能损失......