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 butDispatchQueue.concurrentPerform
creates 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 newasync
API that does “sleep”. It suspends the currentTask
instead 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:
Thread.sleep() |
Task.sleep() |
|
---|---|---|
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 DispatchQueue
:
|
|
GCD spreads the concurrent work on all cores it can grab and on my machine the code prints:
Duration: 9.00s
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 machine is “busy” running nothing.
Let’s have a look at the same code with the new Task
APIs and async/await
:
|
|
Running this code prints:
Duration: 1.05s
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 1
second.
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 at https://twitter.com/icanzilb.