Re: A sink
I disagree.
The use case for “async” is primarily to prevent blocking-waits within threads, not to pre-compute things. The classic example is networked APIs
HttpResultThing result = await fetchURL("http://test.com");
// --- thread yields here until resource is ready.
if (result.IsOk )
{
// do your processing
}
Any equivalent without async either busy-waits, or requires all of the plumbing hidden by “await” to be implemented explicitly in the application, usually creating ideal conditions for callback-hell (“the pyramid of doom”) in the process.
The advantage of having async in the language, and thus the runtime libraries, is that it lowers the cost of doing things the “Right Way”. File I/O, for instance, is a blocking operation, but most C/C++ devs tend to ignore this fact because a call to read() is usually a fast operation... until the files get big, or have to be accessed over a network. A framework where all I/O is asynchronously handled makes applications more responsive to events without needing more threads.
Your second point is also not correct - async is an optional feature: methods are never async by default, and if the Swift runtime is anything like the C# one I’m familiar with, most methods are not async, unless they can block your thread. For the case of Swift, scopes only gain the async plumbing silently if they include an “await” inside (as it makes no sense to use “await” in a non-async context); no “await”: no async.
The truth is, if you really care about performance, you write the bits that need that performance in C, where you have much tighter control over the resources at your disposal. If you’re using any high-level language that’s managing memory and tasks for you, you have already tacitly admitted that you do not require maximum performance for your application.