Частая мысль:
«Добавлю threading → станет быстрее»
На практике — не факт.
В чём причина
В классическом Python есть GIL — он не даёт нескольким потокам выполнять код одновременно.
Поэтому:
✔️ I/O (API, файлы) → быстрее
✔️ CPU (вычисления) → почти нет
С появлением PEP 703 Python постепенно уходит от GIL. Теперь потоки могут работать параллельно.
Где всё ломается:
counter += 1
На деле это: read → compute → write
В потоках это приводит к race condition:
import threading
counter = 0
def worker():
global counter
for _ in range(1_000_000):
counter += 1
threads = [threading.Thread(target=worker) for _ in range(8)]
for t in threads: t.start()
for t in threads: t.join()
print(counter) # ≠ 8_000_000
«Фикс», который замедляет:
lock = threading.Lock()
with lock:
counter += 1
Работает правильно, но: потоки стоят в очереди → параллельности нет
Как правильно:
from concurrent.futures import ThreadPoolExecutor
def worker():
local = 0
for _ in range(1_000_000):
local += 1
return local
with ThreadPoolExecutor(max_workers=8) as ex:
result = sum(ex.map(lambda _: worker(), range(8)))
print(result) # 8_000_000
💡 Главное правило
Потоки не должны делить данные во время работы: делят → медленно, независимы → быстро
📍 Навигация: Вакансии • Задачи • Собесы
Библиотека питониста
#буст