Ответ
На асинхронную модель стоит переносить задачи, связанные с ожиданием операций ввода-вывода (I/O-bound), так как это позволяет процессору не простаивать, а выполнять другую полезную работу, пока программа ожидает ответа.
Идеальные кандидаты для асинхронности:
- Сетевые взаимодействия: HTTP-запросы к внешним API, работа с WebSocket, gRPC.
- Операции с базами данных: Чтение и запись при использовании асинхронных драйверов (например,
asyncpgдля PostgreSQL). - Работа с файловой системой: Асинхронное чтение/запись файлов.
Задачи, не подходящие для асинхронности:
- Вычислительно-интенсивные задачи (CPU-bound): Сложные математические расчеты, обработка изображений, шифрование. Такие задачи блокируют основной поток (event loop), сводя на нет все преимущества асинхронности. Для них лучше использовать многопроцессорность (
multiprocessing).
Пример: Асинхронный HTTP-запрос
import aiohttp
import asyncio
async def fetch_data(url):
# Сессия создается один раз для множества запросов
async with aiohttp.ClientSession() as session:
# Программа не блокируется, а "ожидает" ответа от сервера
async with session.get(url) as response:
print(f"Status: {response.status}")
return await response.text()
# Запуск асинхронной функции
# asyncio.run(fetch_data('https://api.github.com')) Ответ 18+ 🔞
Слушай, а вот этот твой асинхронный пиздец — это ж не просто так, чтобы код красивый был. Это чтобы комп не стоял как идиот, пока какой-нибудь удалённый сервер думает, как ему твой запрос послать нахуй.
Короче, если задача I/O-bound — то есть она в основном ждёт, пока кто-то другой соизволит ответить (сеть, диск, база данных), — то это идеальный кандидат. Процессор в это время может другие дела делать, а не срать кирпичами.
Что можно и нужно пихать в асинхронность:
- Сеть: Все эти твои запросы к API, вебсокеты, gRPC. Пока один запрос летит до Гитхаба и обратно, можно ещё двадцать отправить.
- Базы данных: Но только если драйвер асинхронный, а не старый блокирующий кусок говна.
asyncpg— да, стандартныйpsycopg2— нет, он всё затормозит. - Файлы: Чтение-запись, особенно если файлы большие или их много.
А что НЕЛЬЗЯ, блядь:
- CPU-bound задачи: Всё, где процессор должен пахать без остановки — сложная математика, шифрование, рендеринг. Такая штука заблокирует весь твой event loop, и будет он тупить, как Герасим, когда ему объясняли, зачем топить Муму. Для этого есть
multiprocessing— пусть другие ядра процессора страдают.
Вот, смотри, как это выглядит на практике, чтобы не быть теоретическим пиздаболом:
import aiohttp
import asyncio
async def fetch_data(url):
# Сессия создается один раз для множества запросов
async with aiohttp.ClientSession() as session:
# Программа не блокируется, а "ожидает" ответа от сервера
async with session.get(url) as response:
print(f"Status: {response.status}")
return await response.text()
# Запуск асинхронной функции
# asyncio.run(fetch_data('https://api.github.com'))
Видишь? Пока session.get ждёт ответа от сервера, твоя программа может переключиться и делать что-то ещё. Красота, ёпта! А не как раньше — послал запрос и сиди, хуем груши околачиваешь, пока ответ не прилетит.