Ответ
Пропускная способность (tasks/time) определяется типом очереди и доступными системными ресурсами (ядрами CPU), а не просто количеством потоков.
1. Serial (последовательная) очередь:
- Выполняет задачи строго по одной, в порядке добавления (FIFO).
- Throughput = 1 задача / время_выполнения_задачи.
- Добавление потоков не увеличивает производительность.
let serialQueue = DispatchQueue(label: "com.example.serial")
// Все задачи выполнятся последовательно, одна за другой.
2. Concurrent (параллельная) очередь:
- Может запускать несколько задач одновременно, используя пул потоков.
- Максимальный параллелизм ограничен системой (например,
ProcessInfo.processInfo.activeProcessorCount). - Throughput ≈ min(число_ядер, число_задач_в_очереди) / среднее_время_задачи.
let concurrentQueue = DispatchQueue(label: "com.example.concurrent", attributes: .concurrent)
// На 6-ядерном CPU до 6 задач могут выполняться физически параллельно.
3. Global Queues & QoS:
Системные очереди (DispatchQueue.global()) являются concurrent. Качество обслуживания (QoS) влияет на приоритет получения системных ресурсов, но не на абсолютный лимит параллелизма.
Вывод: Для CPU-bound задач параллелизм ограничен ядрами CPU. Для I/O-bound задач можно добиться большего overlap операций ввода-вывода, но активных потоков, выполняющих код, всё равно будет не больше доступных ядер.