haHAA

Пользователь

Регистрация: 25.03.2017

Сообщения: 1107

Рейтинг: 742

haHAA

Регистрация: 25.03.2017

Сообщения: 1107

Рейтинг: 742

img

Как мы все знаем, в питоне существуют потоки, однако они выполняются в рамках одного процесса асинхронно: т.е. ты не сможешь в один и тот же момент времени совершить несколько операций с помощью потоков. Всё это благодаря GIL, но тема не об этом. Я задался вопросом: в чем тогда разница между многопоточностью и библиотекой asyncio в питоне, если по факту они оба асинхронны.

Наткнулся на хорошую статью:

A better way for asynchronous programming: asyncio over multi-threading | by Qian (Aria) Li | Towards Data Science

Из результатов тестов видно, что при малых количествах запросов многопоточность лучше, чем asyncio (~2 раза)

Однако при больших количествах победителем выходит asyncio (~3 раза)

Мой вопрос - почему так? В статье описана лишь расшифровка результатов, но не причина их возникновения.

Почему выигрывает asyncio - я могу понять: система тратит какое-то время на переключение между потоками при многопоточности в то время, как asyncio работает в одном потоке. Но проигрыш asyncio при малых количествах запросов - вызывает вопросы.

SolarusOne

Пользователь

Регистрация: 30.03.2016

Сообщения: 3389

Рейтинг: 3401

SolarusOne

Регистрация: 30.03.2016

Сообщения: 3389

Рейтинг: 3401

haHAA сказал(а):

Из результатов тестов видно, что при малых количествах запросов многопоточность выигрывает asyncio (~2 раза)

Однако при больших количествах победителем выходит asyncio (~3 раза)

Нажмите, чтобы раскрыть...

Если и там и сям она выигрывает и выходит победителем, то в чём проблема? ShrekWTF.png?1619500548

Hit Girl

Пользователь

Регистрация: 10.12.2014

Сообщения: 4218

Рейтинг: 2066

Hit Girl

Регистрация: 10.12.2014

Сообщения: 4218

Рейтинг: 2066

при 10 реквестах могло произойти что угодно, время на реквест несравнимо выше, чем любая разница между асинком и тредами если она и есть.

Соответственно, замерить это если и возможно, то очень тяжело, а результаты автора сомнительны

haHAA

Пользователь

Регистрация: 25.03.2017

Сообщения: 1107

Рейтинг: 742

haHAA

Регистрация: 25.03.2017

Сообщения: 1107

Рейтинг: 742

img
Hit Girl сказал(а):

при 10 реквестах могло произойти что угодно, время на реквест несравнимо выше, чем любая разница между асинком и тредами если она и есть.

Соответственно, замерить это если и возможно, то очень тяжело, а результаты автора сомнительны

Нажмите, чтобы раскрыть...

Если списывать это на погрешность тестов, то тогда немного другой вопрос - нахрена нужна многопоточка в питоне?

Hit Girl

Пользователь

Регистрация: 10.12.2014

Сообщения: 4218

Рейтинг: 2066

Hit Girl

Регистрация: 10.12.2014

Сообщения: 4218

Рейтинг: 2066

haHAA сказал(а):

Если списывать это на погрешность тестов, то тогда немного другой вопрос - нахрена нужна многопоточка в питоне?

Нажмите, чтобы раскрыть...

я не знаю, мб гуй писать.

Перфоманс CU-bounded потоки не бустят, потому что работает 1 поток.

В реквестах лучше асинк.

Zacateca

Пользователь

Регистрация: 22.12.2017

Сообщения: 34342

Рейтинг: 13379

Нарушения: 35

Zacateca

Регистрация: 22.12.2017

Сообщения: 34342

Рейтинг: 13379

Нарушения: 35

haHAA сказал(а):

Как мы все знаем, в питоне существуют потоки, однако они выполняются в рамках одного процесса асинхронно: т.е. ты не сможешь в один и тот же момент времени совершить несколько операций с помощью потоков. Всё это благодаря GIL, но тема не об этом. Я задался вопросом: в чем тогда разница между многопоточностью и библиотекой asyncio в питоне, если по факту они оба асинхронны.

Наткнулся на хорошую статью:

A better way for asynchronous programming: asyncio over multi-threading | by Qian (Aria) Li | Towards Data Science

Из результатов тестов видно, что при малых количествах запросов многопоточность лучше, чем asyncio (~2 раза)

Однако при больших количествах победителем выходит asyncio (~3 раза)

Мой вопрос - почему так? В статье описана лишь расшифровка результатов, но не причина их возникновения.

Почему выигрывает asyncio - я могу понять: система тратит какое-то время на переключение между потоками при многопоточности в то время, как asyncio работает в одном потоке. Но проигрыш asyncio при малых количествах запросов - вызывает вопросы.

Нажмите, чтобы раскрыть...

да вроде и в статье написано

Спойлер

Как я понял, асинк может остановиться где угодно и отдать ресурсы куда угодно.

Мультитред отдаёт ресурсы блоками, не важно закончишь ты задачу или нет. Поэтому чем больше маленьких задач, тем больше будет простоя.

YoshkinKot

Пользователь

Регистрация: 20.06.2016

Сообщения: 13401

Рейтинг: 5311

YoshkinKot

Регистрация: 20.06.2016

Сообщения: 13401

Рейтинг: 5311

haHAA сказал(а):

Как мы все знаем, в питоне существуют потоки, однако они выполняются в рамках одного процесса асинхронно: т.е. ты не сможешь в один и тот же момент времени совершить несколько операций с помощью потоков. Всё это благодаря GIL, но тема не об этом. Я задался вопросом: в чем тогда разница между многопоточностью и библиотекой asyncio в питоне, если по факту они оба асинхронны.

Наткнулся на хорошую статью:

A better way for asynchronous programming: asyncio over multi-threading | by Qian (Aria) Li | Towards Data Science

Из результатов тестов видно, что при малых количествах запросов многопоточность лучше, чем asyncio (~2 раза)

Однако при больших количествах победителем выходит asyncio (~3 раза)

Мой вопрос - почему так? В статье описана лишь расшифровка результатов, но не причина их возникновения.

Почему выигрывает asyncio - я могу понять: система тратит какое-то время на переключение между потоками при многопоточности в то время, как asyncio работает в одном потоке. Но проигрыш asyncio при малых количествах запросов - вызывает вопросы.

Нажмите, чтобы раскрыть...

разница в подходах

 

asyncio и сходные в других языках концепции это кооперативная многозадачность

корутина в рамках этого протокола останавливается только тогда, когда сама захочет, передавая управление кому-нибудь

 

то есть у нас все операции помимо await и всяких аналогичных конструкций — живут в критической секции кода

критическая секция эта та, что требует полного исполнения кода

 

минусы?

мы ответственны за то, как долго у нас исполняется код каждой корутины

не скажешь await нигде, ну она и исполнится до конца, захватив всё время исполнения

 

зачем нам старая добрая вытесняющая многозадачность?

ну условно у нас есть много разных не особо зависимых друг от друга "потоков кода", которые вычисления на фоне должны по нашей задумке делать и изредка синхронизироваться

и мы не очень хотим париться по поводу того, чтобы это было всё максимально эффективно и имело нормальный отклик

 

поэтому мы просто создаём потоки и передаём по сути всю головную боль операционной системе

пусть она и её планировщик планирует: сама останавливает и передаёт управление между разными потоками

 

минусы?

головная боль с обычными потоками начинается, когда они сильно друг от друга зависят, имеют много критических секций

и нам надо организовывать бесконечно сложные танцы с семафорами и прочими механизмами синхронизации

 

потому что в отличие от корутин исполнение потока может быть прервано в любой момент и мы не можем ничего особо гарантировать, если не позаботились о синхронизациях заранее

 

короче, учитывая, что (как я понял) event loop умеет работать со всеми: процессам, потокам и корутинами, то ты просто можешь смешивать эти вещи вместе и жить как царь RoflanTsar.png 

 

haHAA сказал(а):

Если списывать это на погрешность тестов, то тогда немного другой вопрос - нахрена нужна многопоточка в питоне?

Нажмите, чтобы раскрыть...

в общем, отвечая на твой вопрос, для того, чтобы был выбор между разными инструментами, которые не взаимозаменимы

Salovar

Пользователь

Регистрация: 12.07.2017

Сообщения: 4783

Рейтинг: 1007

Salovar

Регистрация: 12.07.2017

Сообщения: 4783

Рейтинг: 1007

потому что в 99% это понты. берешь тот же pyqt и используешь и треды, и тредпулы и все, что хочешь. в чем отсутствие многопотока лично я так и не понял, так как на мой взгляд все было нормально.

haHAA

Пользователь

Регистрация: 25.03.2017

Сообщения: 1107

Рейтинг: 742

haHAA

Регистрация: 25.03.2017

Сообщения: 1107

Рейтинг: 742

img
YoshkinKot сказал(а):

корутина в рамках этого протокола останавливается только тогда, когда сама захочет, передавая управление кому-нибудь

Нажмите, чтобы раскрыть...

Насколько я понял, здесь речь идет о том, что в asyncio оркестрацией занимается интерпретатор, а не ОС как при потоках

YoshkinKot сказал(а):

вычисления на фоне должны по нашей задумке делать

Нажмите, чтобы раскрыть...

Я вычитал, что, если у тебя должны быть какие-то вычисления (CPU bound), то пользуйся multiprocessing и не в ус не дуй

YoshkinKot

Пользователь

Регистрация: 20.06.2016

Сообщения: 13401

Рейтинг: 5311

YoshkinKot

Регистрация: 20.06.2016

Сообщения: 13401

Рейтинг: 5311

haHAA сказал(а):

Насколько я понял, здесь речь идет о том, что в asyncio оркестрацией занимается интерпретатор, а не ОС как при потоках

Нажмите, чтобы раскрыть...

по идее хуже

 

мы сами ей и занимаемся: никто (ну в рамках программы) наше исполнение прервать не может

в случае с тредами и процессами — мы не контролируем, когда нас могут прервать

 

короче это как наличие сборщика мусора и управление памятью ручками на мой взгляд, если аналогии брать

 

haHAA сказал(а):

то пользуйся multiprocessing

Нажмите, чтобы раскрыть...

ну там свои резоны могут быть вроде того, что процесс создать — это адъ и израиль для системы

там пока семь кругов навернешь, может уже и не нужен будет никакой процесс

 

 

Salovar сказал(а):

потому что в 99% это понты. берешь тот же pyqt и используешь и треды, и тредпулы и все, что хочешь. в чем отсутствие многопотока лично я так и не понял, так как на мой взгляд все было нормально.

Нажмите, чтобы раскрыть...

с GIL отсутствует параллелизм потоков, а не многопоточка

это вынуждает тебя переносить модули в C, если нужен именно параллелизм

 

с другой стороны весь мем в том, что GIL и существует, чтобы вы могли модули в C переносить с большей простотой

потому это просто design choice конкретного интерпретатора, с которым ты либо соглашаешься, либо идёшь в сторонние интерпретаторы

 


ну короче, лучше всего понять что-то, в том числе в терминах достоинств и недостатков, когда ты можешь это реализовать ручками сам PekaPled.png?1619501252

поэтому:

https://tenthousandmeters.com/blog/python-behind-the-scenes-12-how-asyncawait-works-in-python/

 

 

NbW

Пользователь

Регистрация: 10.03.2016

Сообщения: 1526

Рейтинг: 456

NbW

Регистрация: 10.03.2016

Сообщения: 1526

Рейтинг: 456

YoshkinKot сказал(а):

ну короче, лучше всего понять что-то, в том числе в терминах достоинств и недостатков, когда ты можешь это реализовать ручками сам PekaPled.png?1619501252

поэтому:

https://tenthousandmeters.com/blog/python-behind-the-scenes-12-how-asyncawait-works-in-python/

Нажмите, чтобы раскрыть...

раз на то пошло, то вот: https://www.youtube.com/playlist?list=PLlWXhlUMyooawilqK4lPXRvxtbYiw34S8

возможно здесь будет ответ на вопрос @haHAA , либо будет пища, чтобы разобраться самому

haHAA

Пользователь

Регистрация: 25.03.2017

Сообщения: 1107

Рейтинг: 742

haHAA

Регистрация: 25.03.2017

Сообщения: 1107

Рейтинг: 742

img
NbW сказал(а):

раз на то пошло, то вот: https://www.youtube.com/playlist?list=PLlWXhlUMyooawilqK4lPXRvxtbYiw34S8

возможно здесь будет ответ на вопрос @haHAA , либо будет пища, чтобы разобраться самому

Нажмите, чтобы раскрыть...
смотрел)

MEDI_OFF

Пользователь

Регистрация: 19.07.2018

Сообщения: 57

Рейтинг: 17

MEDI_OFF

Регистрация: 19.07.2018

Сообщения: 57

Рейтинг: 17

img

Если ответить коротко то проблема в криво написанном планировщике у дефолтного event loop в asyncio, если брать более производительную реализацию, тот же uvloop то проблема уйдет, ибо там ребята оч постарались, и приблизились к гошному планировщику. А если хочешь более развернутого ответа, то мне впадлу печатать, если захочешь в личку отпиши, ну или почитай "Asyncio и конкурентное программирование на Python"

Mask of Sadness

Пользователь

Регистрация: 12.06.2020

Сообщения: 2458

Рейтинг: 1399

Mask of Sadness

Регистрация: 12.06.2020

Сообщения: 2458

Рейтинг: 1399

Не шарю за питон, но асинхронность и многопоточность это совсем разные вещи 

MEDI_OFF

Пользователь

Регистрация: 19.07.2018

Сообщения: 57

Рейтинг: 17

MEDI_OFF

Регистрация: 19.07.2018

Сообщения: 57

Рейтинг: 17

img
haHAA сказал(а):

Если списывать это на погрешность тестов, то тогда немного другой вопрос - нахрена нужна многопоточка в питоне?

Нажмите, чтобы раскрыть...

Ну самое первое это не для всего у нас есть асинхронные обертки, а некоторые асинхронные обертки работают как раз на потоках, проще говоря иногда у нас есть только синхронные библиотеки и тут нам нужны треды что бы оптимизировать производительность. Второе - не надо забывать что под капотом у нас C, и если тебе хочется то можешь писать расширения на нем, а там у тебя уже есть механизмы поднятия и опускания GIL которые как раз таки и отрубают и врубают эту историю (тот же Numpy так делает в ресурсоемких задачах, типо перемножения матриц).