首页 > 解决方案 > C#异步任务比同步慢

问题描述

你知道为什么同步斐波那契方法比 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();
            }
        }

结果:

标签: c#.netasync-await

解决方案


你知道为什么同步斐波那契方法比 async/await 快,而且比异步任务快吗?

异步不是提高原始速度。正如您所发现的,总体上需要更长的时间。如果你使用得不好,就像你所做的那样,它会使事情变得非常非常慢,而零收益。

这里的根本问题是您不了解异步的用途。异步用于管理延迟。一旦你内化了这个事实,你就会开始正确地使用它。

延迟是您请求计算或副作用与计算或副作用完成之间的时间间隔。

例如,假设您正在计算一些计算量非常大的东西。例如,您正在计算一个非常复杂的图形,即使您将整个内核都用于计算它也需要 30 多毫秒。您不希望用户界面在进行计算时停止,因此您可以将计算放到另一个线程上,将 CPU 专用于该线程,然后等待结果。 等待的意思是“在等待高延迟操作完成时去找更多的工作要做”

例如,假设您正在做一些计算成本高但需要等待外部资源的事情。例如,您正在调用数据库,并且需要 30 多毫秒才能返回结果。在这种情况下,您不想启动线程。该线程只是要睡觉等待结果!相反,您想使用数据库访问 API 的异步版本,并等待高延迟结果

在您的示例中,您一开始就没有高延迟操作,因此等待它是没有意义的。您在那里所做的只是为运行时创建和管理工作队列创建大量工作,这是您付出但没有从中受益的工作。你的工作需要纳秒仅对需要毫秒或更长时间的作业使用异步。

仅当您有高延迟操作时才使用异步。异步提高了性能,因为它释放了一个线程以在等待高延迟结果出现时继续工作。如果没有高延迟结果,那么异步只会减慢一切。


推荐阅读