-1

Can calling await in the same line as the async method be slower than calling normal method?

From what I know asynchronous methods are good for I/O operations like getting data from the database. But what if there is nothing to do between calling the async method and awaiting it I need to do it in the same line.

In this post Await and Async in the same line they discussed that the benefit comes from freeing thread.

I have some unit tests for testing my services and methods using async methods as I described are always taking longer than their non-async equivalents. I assume it's because creating work in a separate thread and then awaiting it has some price.

So what I want to ask is, if using async in this case has truly some benefits.

public async Task AssignHighestRank(User user)
{
    user.Rank = await _rankRepository.GetHighestRank();
    _userRepository.Update(user);
    await _userRepository.SaveChanges();
}
Michalides
  • 152
  • 1
  • 8
  • `Can calling await in same line as async method be slowe than calling normal method?` Yes. – mjwills Jun 14 '19 at 12:20
  • 1) You're worried about the miniscule overhead of using IOCP when dealing with I/O? 2) [there is no thread](https://blog.stephencleary.com/2013/11/there-is-no-thread.html) when dealing with async I/O 3) not all cases of `async/await` are used with I/O, the other is with CPU-bound operations in which case a thread is used. `async/await` is the contemporary and recommended way of performing concurrent programming –  Jun 14 '19 at 12:22
  • The edit history of this question looks like a tiny war^^ – Rabban Jun 14 '19 at 12:29
  • @Rabban Rather, it looks like the OP has troubles using the interface – Camilo Terevinto Jun 14 '19 at 12:30
  • @MickyD 1) not sure if I understand your question but the async version take twice as long as normal version. 2) Isn't work done in separate thread when working with database? – Michalides Jun 14 '19 at 12:30
  • 1
    @Michalides _" async version take twice as long "_ - extraordinary claims require extraordinary evidence. 2) No. Did you even read that post? Using IOCP is always going to be more efficient since there is no thread (instant memory win for one) than using an expensive blocking thread –  Jun 14 '19 at 12:33
  • 3
    It seems like your questions are all answered by the answer you linked to: "That kind of usage brings higher scalability." and "**Async methods don't magically run faster**, but they do potentially use less resources and you can usually run multiple ones concurrently." – Stephen Cleary Jun 14 '19 at 12:35
  • Method might be run faster then regular method if it executes independents operations with Task.WaitAll(tasks) but in case sequential operations it is not fast as regular. – Oleg Bondarenko Jun 14 '19 at 12:40
  • Your `async` method returns `void`. Although this is allowed, you should return `Task` instead to let calling methods exploit your method's asynchronicity. – Sergey Kalinichenko Jun 14 '19 at 12:42

2 Answers2

2

async implementation uses additional CPU cycles, so in this sense an async method would be slightly slower than its equivalent that is not asynchronous. However, using such method together with other async methods may improve performance.

For example, consider a situation when you need to make multiple changes at once:

public async Task RecordBattleResultAsync(User winner, User loser) {
    await Task.WhenAll(
         AssignHighestRankAsync(winner)
    ,    AssignLowestRankAsync(loser)
    ).ConfigureAwait(false);
}

This method would exploit the fact that both your methods are async for a potential speed-up.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thank you. This was the first usefull answer. So can I undersrand it like don’t always use asynchronous methods always when you can? – Michalides Jun 14 '19 at 12:45
  • 1
    @Michalides In C# `async` is "contagious", in the sense that if something needs to be `async`, everything else down from it needs to be `async` as well. That is why it is a good practice to use `async` whenever it is available, on the chance that the caller would want to benefit from it. This way it's there in case you need it, and there's very little overhead in case you don't need it. – Sergey Kalinichenko Jun 14 '19 at 12:57
-1

Based on this investigation async method works slowly with consistently operations then regular one does the same (if we do not regard that async methods does not hold execution thread unlike regular one) :

Should I worry about "This async method lacks 'await' operators and will run synchronously" warning

due to huge amount of compiler's works under the hood. But using operation Task.WhenAll (creation task that is completed when all task are completed too - main thread is not blocked) and Task.WaitAll (almost the same save for main thread is blocked) with independence data task might increase speed-up of method execution (methods but not whole application in case Task.WaitAll) because of parallel task execution .

Oleg Bondarenko
  • 1,694
  • 1
  • 16
  • 19
  • 2
    _"background compiles work"_ - you are sort of implying that at runtime there will be background compilation going on hurting performance. In actual fact, the `async/await` sugar syntax is expanded into extra code by the compiler and compiled at compile-time at the same time as the rest of your code. –  Jun 15 '19 at 00:25
  • 2
    How would `Task.WhenAll` and `Task.WaitAll` speed-up method execution? Now you are blocking the calling thread. If you are going to synchonously wait on a single task then its better not to use a task at all as it defeats the purpose. Same with spawning a `Thread` and calling `Join()` –  Jun 15 '19 at 00:29
  • @MickyD I sure you did not look link to my other anwser where IL version of c# code is presented. "background compiles work" might be not the best descibing compilation process it should be "background compilers work" or " compiler's works under the hood" – Oleg Bondarenko Jun 15 '19 at 06:30
  • @MickyD Thanks you for attention to this post. It just means `Task.WhenAll` and `Task.WaitAll` runs task in parallel execution inside the same method. And Yes it is decrease execution time and speed-up method execution. – Oleg Bondarenko Jun 15 '19 at 06:35
  • 1
    I did read the link actually. I found a problem with your conclusion over there too so I'm not sure how useful it is to cite it here. You should not just flippantly use `Task.WaitAll`, it blocks the current thread. You use those methods when you explicitly want to synchonise when they are complete. It is not necessary to call `Task.WhenAll/WaitAll` just to ensure tasks run concurrently (parallel). The mere act of instantiating a `Task` (e.g. via `Task.Run`) is sufficient –  Jun 15 '19 at 08:29