Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Asynchronous with task is slower than synchronous

Do you know why sync fibonacci method is faster than async/await and that is faster than async task?

I used async on every project method, so it's main this is so bad approach...

Code:

        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();
            }
        }

Result:

  • Sync: 00:00:00.0121900
  • Await: 00:00:00.2118170
  • Async: 00:00:02.6211660
like image 726
Mohsen Samiei Avatar asked Sep 18 '18 19:09

Mohsen Samiei


1 Answers

Do you know why sync fibonacci method is faster than async/await and that is faster than async task?

Asynchrony is not about improving raw speed. As you've discovered, it takes longer overall. If you use it poorly, as you have done, it makes things much, much slower for zero benefit.

The fundamental problem here is that you don't understand what asynchrony is for. Asynchrony is for managing latency. Once you internalize that fact, you'll start using it correctly.

Latency is the gap in time between when you request a computation or side effect, and when the computation or side effect is complete.

For example, suppose you are computing something that is extremely computationally expensive. You're computing a really complicated graphic, for example, and it is going to take more than 30 milliseconds to compute even if you dedicate an entire core to it. You do not want your user interface to stall while you're doing the computation, so you can put the computation onto another thread, dedicate a CPU to that thread, and await the result. An await means "go find more work to do while I am waiting for a high latency operation to complete".

For example, suppose you are doing something that is not computationally expensive but requires waiting on an external resource. You're calling into a database, for example, and it is going to take more than 30 ms to get the result back. In this case you do not want to spin up a thread. That thread is just going to sleep waiting for the result! Instead you want to use the async version of the database access API, and await the high latency result.

In your example you don't have a high-latency operation to begin with, so it makes no sense to await it. All you're doing there is creating a lot of work for the runtime to create and manage the work queues, and that is work you are paying for but getting no benefit from. Your work takes nanoseconds; only use asynchrony for jobs that take milliseconds or longer.

Only use async when you have a high-latency operation. Async improves performance because it frees up a thread to keep on doing work while it is waiting for a high-latency result to appear. If there is no high-latency result then async will just slow everything down.

like image 69
Eric Lippert Avatar answered Oct 20 '22 01:10

Eric Lippert