Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does an async single task run faster than a normal single task?

I have a method which has just one task to do and has to wait for that task to complete:

public async Task<JsonResult> GetAllAsync()
{
    var result = await this.GetAllDBAsync();
    return Json(result, JsonRequestBehavior.AllowGet);
}

public async Task<List<TblSubjectSubset>> GetAllDBAsync()
{
    return await model.TblSubjectSubsets.ToListAsync();
}

It is significantly faster than when I run it without async-await. We know

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active

According to this link: https://msdn.microsoft.com/en-us/library/hh191443.aspx#BKMK_Threads. What is the reason for being faster when we don't have another thread to handle the job?

like image 228
Hamid Bahmanabady Avatar asked Dec 10 '22 22:12

Hamid Bahmanabady


2 Answers

"Asynchronous" does not mean "faster."

"Asynchronous" means "performs its operation in a way that it does not require a thread for the duration of the operation, thus allowing that thread to be used for other work."

In this case, you're testing a single request. The asynchronous request will "yield" its thread to the ASP.NET thread pool... which has no other use for it, since there are no other requests.

I fully expect asynchronous handlers to run slower than synchronous handlers. This is for a variety of reasons: there's the overhead of the async/await state machine, and extra work when the task completes to have its thread enter the request context. Besides this, the Win32 API layer is still heavily optimized for synchronous calls (expect this to change gradually over the next decade or so).

So, why use asynchronous handlers then?

For scalability reasons.

Consider an ASP.NET server that is serving more than one request - hundreds or thousands of requests instead of a single one. In that case, ASP.NET will be very grateful for the thread returned to it during its request processing. It can immediately use that thread to handle other requests. Asynchronous requests allow ASP.NET to handle more requests with fewer threads.

This is assuming your backend can scale, of course. If every request has to hit a single SQL Server, then your scalability bottleneck will probably be your database, not your web server.

But if your situation calls for it, asynchronous code can be a great boost to your web server scalability.

For more information, see my article on async ASP.NET.

like image 59
Stephen Cleary Avatar answered Dec 13 '22 11:12

Stephen Cleary


I agree with Orbittman when he mentions the overhead involved in the application architecture. It doesn't make for a very good benchmark premise since you can't be sure if the degradation can indeed be solely attributed to the async vs non-async calls.

I've created a really simple benchmark to get a rough comparison between an async and a synchronous call and async loses every time in the overall timing actually, though the data gathering section always seems to end up the same. Have a look: https://gist.github.com/mattGuima/25cb7893616d6baaf970

Having said that, the same thought regarding the architecture applies. Frameworks handle async calls differently: Async and await - difference between console, Windows Forms and ASP.NET

The main thing to remember is to never confuse async with performance gain, because it is completely unrelated and most often it will result on no gain at all, specially with CPU-bound code. Look at the Parallel library for that instead.

like image 27
Matheus Guimaraes Avatar answered Dec 13 '22 10:12

Matheus Guimaraes