libdispatch efficiency tips

The libdispatch is one of the most misused API due to the way it was presented to us when it was introduced and for many years after that, and due to the confusing documentation and API. This page is a compilation of important things to know if you're going to use this library. Many references are available at the end of this document pointing to comments from Apple's very own libdispatch maintainer (Pierre Habouzit).

My take-aways are:

@tclementdev

References

This long discussion on the swift-evolution mailing-list started it all (look for Pierre Habouzit).

Use very few queues

Go serial first

Don't use global queues

Avoid concurrent queues in almost all circumstances

Don't use async to protect shared state

Don't use async for small tasks

Some classes/libraries should just be synchronous

Contention is a performance killer for concurrency

To avoid deadlocks, use locks to protect shared state

Don't use semaphores to wait for asynchronous work

Synchronous IPC is not bad

The NSOperation API has some serious performance pitfalls

pthread_mutex has been changed to be an unfair lock

Locks are not as bad as people think they are (from libdispatch's original designer)

Avoid micro-benchmarking

Resources are not infinite

Background QOS work is paused when low-power mode is enabled

About dispatch_async_and_wait()

Utilizing more than 3-4 cores isn't something that is easy

A lot of iOS 12 perf wins were from daemons going single-threaded

This page is the real deal