Если ваши запросы не связаны с IO, вы не увидите много изменений. - Me
В программировании это основные ограничения, которые мы имеем:
- CPU (количество вычислений, которые могут произойти в секунду)
- доступа кэша в процессоре
- доступа ОЗУ
- Доступ к дискам
- Доступ к сети
В Python мы еще больше ограничены, когда речь идет о доступе к ЦП из-за GIL. С современными компьютерами, которые имеют тенденцию к нескольким ядрам - 2, 4, 8 или 16 - мы калекой еще больше, потому что обычно каждый из этих процессоров будет немного медленнее. Для получения дополнительной информации о GIL, проверьте David Beazley's GIL talk и Larry Hasting's GIL-ectomy.
Чтобы обойти глобальную блокировку интерпретатора, было разработано несколько модулей обратного вызова, таких как Twisted, Tornado и asyncio. Способ, которым они работают, заключается в выполнении некоторых операций, обычно приводящих к управлению, когда они достигают точки, где останавливается IO.
Например, если я пишу данные на вращающийся диск, возможно, я могу записать 100 кб на диск, но пока я жду, когда вся эта информация будет написана, возможно, я смогу уйти и сделать 1000 расчеты до того, как все данные завершат запись.
В качестве альтернативы, возможно, я могу сделать 100 запросов в секунду для веб-службы, но мне требуется 0,0001s для выполнения моих расчетов для каждого из этих запросов. Если посмотреть на график, где я провожу время это будет выглядеть примерно так:
#
#
#
#
#
#
#
# #
--------------------------
reading processing
То, что эти процессы позволяют сделать чередовать обработку и чтение/запись, отправив запрос пакетов от , затем делать что-то еще, а затем в какой-то момент вернуться к чтению возвращенных пакетов.
Существо IO связаны, как это, вы можете увидеть довольно массивное ускорение, потому что вместо того, чтобы искать что-то вроде этого:
start end start end
--|--------|----|--------|------
t=0 t=5 t=6 t=11
Вы можете получить что-то вроде этого:
start end
start| end |
--|---|------|---|-
t=0 t=1 t=5 t=6
Но если ваш процесс связан с ЦП, вы не увидите какого-либо из этих ускорений (или, по крайней мере, не так много), потому что вы тратите 30 секунд на обработку, и только 1s делает ожидания в сети.
Перед тем как попробовать асинхронный подход, дайте стандартный однопоточный подход и посмотрите 1) если он достаточно быстрый и 2) если он медленный на границе сети/IO.
Вы можете легко использовать что-то вроде line profiler для Python, и (если еще не) выделить функции чтения, обработки и записи и посмотреть, где вы проводите время. Если вы тратите большую часть времени на функции чтения, тогда да, вы должны увидеть довольно разумное ускорение от асинхронного подхода. Если нет, async просто замедлит вас.
Честно говоря, это не так уж плохо, если у вас есть что-то супер скорость критической. И тогда вы должны использовать cffi или что-то, чтобы взять критические разделы скорости и свалить их на C. Вы сделали выяснить, какие разделы являются задержкой, не так ли?
Если ваши запросы не связаны с IO, вы не увидите много изменений. –
Не могли бы вы объяснить мне немного больше? :) –