The difference between Thread.sleep() and Task.sleep()
With the work-in-progress backport of the new Swift concurrency model all the way to iOS13,
async/await and friends are getting more and more relevant for all Swift developers.
So here’s a quick and simple example that showcases some of the nice features of the new concurrency model without going into much detail.
Thread.sleep() vs Task.sleep()
Let’s just look at the old and new sleep APIs:
Thread.sleep()is the old API that blocks a thread for the given amount of seconds — it doesn’t load the CPU, the core just idles. Edit: Turns out the core doesn’t idle but
DispatchQueue.concurrentPerformcreates only as many threads as there are cores so even if the blocked treads don’t do anything it doesn’t create more threads to do more work during this time.
Task.sleep()is the new
asyncAPI that does “sleep”. It suspends the current
Taskinstead of blocking the thread — that means the CPU core is free to do something else for the duration of the sleep.
Or to put them side by side:
|Blocks the thread||Suspends and lets other tasks run|
|Slow switching of threads on same core||Quickly switching via function calls to a continuation|
|Rigid, cannot be cancelled||Can be cancelled while suspended|
|Code resumes on the same thread||Could resume on another thread, threads don’t matter|
The difference in practice
What do these mean in practice? This is how you’d concurrenty have
100 sleeps with
GCD spreads the concurrent work on all cores it can grab and on my machine the code prints:
The thing is — you’re limited to the amount of threads
DispatchQueue will create for you as switching threads is very expensive and the system will try creating as few as possible. In the end the whole laptop is busy running a whole bunch of blocked threads.
Let’s have a look at the same code with the new
Task APIs and
Running this code prints:
While suspended, a
Task takes no CPU core-seconds so the same core can run all of the hundred sleep tasks at the same time. You can have thousands of them if you want and the duration will still be just over
In the new model, asynchronous tasks collaborate by suspending when not actively doing work so all of the currently scheduled work can progress forward.
Thanks for reading and see you next time 👋🏽
Where to go from here?
Interested in the new
async/await Swift syntax? Hit me up on twitter if you think I should write a short book about it to cover everything in detail: https://twitter.com/icanzilb.
To learn about all Combine check Combine: Asynchronous programming with Swift - this is where you can see all updates, discuss in the website forums, and more.