Returning Awaited methods vs Tasks
08/12/2018
2 minutes
I have come across this question several times, I thought it might worth a little investigation. Which of the following method runs faster TestAsync or TestDirect, given the Sum method?
public async Task<int> TestAsync(int a, int b) => await Sum(a, b); public Task<int> TestDirect(int a, int b) => Sum(a, b); public Task<int> Sum(int a, int b) => Task.FromResult(a + b);
At first look there is not much difference, but if we look at the performance of them, one executes faster.
At second look we could assume TestDirect must be faster as the compiler 'probably' does not convert it to a state machine. Or is the compiler smart enough to optimize away the state machine in case of TestAsync?
Looking at the IL code should clarify that, here is TestDirect:
Comparing it with the TestAsync method. Without being fully complete I only show the initialization of the state machine, not the state machine itself:
After seeing all this one might wonder, how much faster it is at runtime, after JIT optimizations?
On my machine, invoking both 100000000 times (Release mode, optimized, netcoreapp2.1) took an average of 3 separate benchmarking:
TestAsync 5870 msTestDirect 1423.4 ms
One might still ask, if the awaited method performs better if we set ConfigureAwait(false), but in this example it only slows down the execution according to my measurements.
Note that awaiting a Task might result in an exception to be thrown, which requires the state machine.