Тёмный

Дизассемблируем Python-циклы. Ассимиляция Гиперпространственного Фокала Социалистических Измерений! 

Диджитализируй!
Подписаться 163 тыс.
Просмотров 13 тыс.
50% 1

Мой курс «Хардкорная веб-разработка» - course.to.digital
Книжный клуб Ботаним!, где мы читаем хорошие ИТ-книги: botanim.to.digital/
Telegram - t.me/t0digital
Препарируем Python-циклы по полной!
0:00 Стартуем
0:31 О чём речь
1:14 Всё дело в обходе структуры!
8:24 Надо просто вынести range за функции!
10:37 Что такое итерация?
19:39 Упрощаем код
20:09 Адовые тесты!
23:13 А если переписать на while?
24:11 while работает медленнее, чем for?
26:12 Выводы
Первое видео - • Ускоряем вложенные цик...
/****************** about ******************/
Меня зовут Алексей Голобурдин, я программирую с 2004 года и на этом канале делюсь своим опытом. Я основатель и руководитель компаний:
- Диджитализируй digitalize.team, разрабатываем сложные IT системы для бизнеса;
- Salesbeat salesbeat.pro, комплексный модуль доставки для интернет магазинов.
Telegram канал - t.me/t0digital
ВК - digitalize.team
RuTube - rutube.ru/channel/24802975/ab...
Дзен - dzen.ru/id/6235d32cb64df01e6e...

Опубликовано:

 

19 июн 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 106   
@user-ir4vd5yk4x
@user-ir4vd5yk4x 28 дней назад
"для тех кто возбудился услышав пайтон и компилятор" .... поздравляю вы вылечены от импотенции при помощи пайтона
@user-oj2vj4rc5f
@user-oj2vj4rc5f 27 дней назад
Обожаю
@losos6069
@losos6069 28 дней назад
1:16 > Поэтому у тебя такой результат получается т.к. тут речь про мой коммент под прошлым видосом, то отвечу) Я отметил в комментах что эксперемент проведен не совсем ЧИСТО и что кеши МОГЛИ повлиять на результат P.S. Я не из тех адептов которые пишут что ты неправильно итерации посчитал P.S.S. Братан, хорош, давай, давай, вперёд! Контент в кайф, можно ещё? Вообще красавчик! Можно вот этого вот почаще?
@roldexX
@roldexX 5 дней назад
Раньше об этом не задумывался, а сейчас прошёлся по операциям и понял даже как посчитать разницу в итерациях, по сути в этих примерах отличается только количество раз прохождения точки вхождения в циклы, а именно там создаётся переменная
@NN-jx8kb
@NN-jx8kb 28 дней назад
Спасибо вам за видео. Мне очень нравится ваша подача материала, всегда приятно смотреть и слушать
@t0digital
@t0digital 28 дней назад
Спасибооо!
@7IdE
@7IdE 22 дня назад
Вот от while на счетчиках я вообще такой подставы не ожидал. Т.е, у for под капотом будет создаваться итератор, который на каждой итерации будет илдить новый элемент. И все это это будет завернуто в try/except, чтобы ловить StopIteration. И все вот это дело быстрее чем счетчики в while?... Я аж у себя проверил - реально быстрее. Я так понимаю, тут прикол в том, что в случае со счетчиками в while мы там руками прописываем инкременты, а вот в случае for - там это уже прописано где-то глубоко под сишным капотом. Но это все равно какая-то прям мистика. Респект за такой видос!
@Vjidowkdkcpapqkfjfw
@Vjidowkdkcpapqkfjfw 28 дней назад
Это как после того что в питоне нет переменных - понял) Надо смотреть, будет больно, но полезно)
@user-zn5nr1cr4b
@user-zn5nr1cr4b 28 дней назад
Спасибо за видео! Справедливости ради хочется отметить, что если в цикле производится какая-то операция, по которой определяется условие его выхода, то while все же может быть быстрее :) К примеру, если часть вычислений уровнять (по примеру с видео): from functools import partial import timeit def for_loop(count: int): counter = 0 for _ in range(count): counter += 1 def while_loop(count: int): counter = 0 while counter < count: counter += 1 x = timeit.timeit(partial(for_loop, 1_000_000), number=100) y = timeit.timeit(partial(while_loop, 1_000_000), number=100) print(x, y, x / y) #x=2.7985 y=2.026 d=1.381 то while окажется быстрее до 40%
@merzbow7
@merzbow7 28 дней назад
Если уж говорить про декартово произведение, то тут вложенный цикл и не нужен, можно обойтись одним for row, col in product(range(5), range(2)):
@t0digital
@t0digital 28 дней назад
можно
@t0digital
@t0digital 28 дней назад
Погонял тесты - работает медленнее, чем вложенные циклы с меньшим внешним циклом. Потому что будет больше проходов по данным. Сначала чтобы собрать пары, потом чтобы пройти пары и что-то с ними сделать.
@user-fx7pt8gd1s
@user-fx7pt8gd1s 28 дней назад
13:03 вообще, оч хороший пример, потому что в нем играют роль не только сами накладные расходы на циклы, но и, например, всякие кэши и конвейеризации на процессоре. Поэтому компиляторы многих языков циклы разворачивают по возможности или "подразворачивают", то есть в теле цикла пишут N раз одно и тоже, и количество итераций делят на N
@user-kt2pf5bf5m
@user-kt2pf5bf5m 27 дней назад
Долго не мог понять, почему количество итераций разное, а потом написал эти 2 цикла и сразу понял)
@harry-smith404
@harry-smith404 28 дней назад
лайк чисто за разбор байткода, многим будет интересно(наверное), тк, полагаю, мало народу вообще смотрит, как оно работает под капотом
@notacatbeaver7853
@notacatbeaver7853 20 дней назад
Спасибо за пояснение к видео! А то алгопрогерский опыт не дал понять что имелось в виду под итерацией
@RedkeiGost
@RedkeiGost 28 дней назад
Минуточку! Эдак и до спецификации не далеко.
@vitaliy3521
@vitaliy3521 28 дней назад
Так эти накладные расходы никак не скалируются, т.е. если мы добавим в цикл какое-то полезное действие(sleep(0.1)), то эти десятитысячные секунды так и останутся десятитысячными, а время выполнения будет примерно одинаковым. Правильно же?
@t0digital
@t0digital 28 дней назад
Да, об этом есть в выводах. Но 0.1с это ооочень до фига даже для медленного питона
@gnompirogov9259
@gnompirogov9259 28 дней назад
Алексей, спасибо за детальны разбор. Такой момент, мной, замечался ранее, около года назад. Но, вы, разобрали на достаточно детальных примерах. Интересно :))) Спасибо
@dmitry-lz1ny
@dmitry-lz1ny 28 дней назад
Если вы побудите в комьюнити других языков, то там не редко говорят, что в питоне очень хреново работает for и while. На том же C C++ в разы лучше, ну ладно это такое себе сравнение. В целом лучше избегать циклы в питоне. : )
@nakamasama
@nakamasama 28 дней назад
А потом и сам Питон, а после и вообще всё программирование избегайте... Чем Вы предлагаете заменить циклы? Goto и спагетти-кодом?
@dmitry-lz1ny
@dmitry-lz1ny 28 дней назад
@@nakamasama Так я не писал, что отказываться надо. Если их можно избежать, то лучше делать именно так. В любом случае те кто часто работает с математикой, те используют нумпай и аналоги (ну дата сатанисты) А отказаться от питона это будущее проекта, который превращается в хайлоад : )
@nakamasama
@nakamasama 28 дней назад
@@dmitry-lz1ny , крутой ответ. Согласен, переход на другой язык качественно улучшает проект👍. И про нампай не поспоришь... Он ведь на С++ написан, а в Питоне просто оболочку имеет. Простите, но лично для меня избегать и отказаться в общем понимании значат одно и то же.
@john.darksoul
@john.darksoul 28 дней назад
У меня есть подозрение, что самая тяжёлая операция в байткоде в начале - это GET_ITER, или что-то типа того. И получается, что итератор (а не итерация) создаётся либо 6 раз, либо 101 раз. Классическая тема, по-моему, просто питон это скрывает от пользователя. Скорее всего, если повторить этот тест с вложенными while со счётчиками, разницы не будет. Проверять я это, конечно, не буду, потому что мне лень :D
@user-eg3jf9dw5c
@user-eg3jf9dw5c 28 дней назад
надо перевести столь удачный термин на английский и попробовать на SO спросить, интересно что подумают.
@gsm7490
@gsm7490 28 дней назад
Крутой материал! Это же все началось с «чистого кода», если не ошибаюсь? И вона куда занесло ) Я периодически начинаю переходить на плюсы или ржавчину, когда думаю о скоростях исполнения, но когда вспоминаю, сколько там всего надо написать, чтобы решить простую задачку, все проходит )
@shaltayb0ltay
@shaltayb0ltay 26 дней назад
Автор ответил на все возникшие у меня при просмотре каверзные вопросы. Подписался. При этом укрепился в мнении, что python - язык, что позволяет быстро писать медленно работающий код.
@t0digital
@t0digital 26 дней назад
Python на данный момент самый медленный из большой скриптовой тройки Node, PHP, Python. Но работа над его ускорением идет. Обещается пятикратный рост скорости. JIT вот завозят в 3.13
@km-academy_ru
@km-academy_ru 27 дней назад
То что цикл несет дополнительные издержки, ясно уже интуитивно просто потому, что цп приходится исполнять инструкции оператора for
@MrLagger1996
@MrLagger1996 28 дней назад
добвлю так чисто хрень, во время прыжка по инструкциям часто происходит промах в кэш и тд, но питон очень дубовый в этом плане, если эту задачу на си написать, то будет работать ровно наоборот. контекст внутреннего цикла будет храниться внутри кэша. чем больше прыжков по инструкциям сделать, тем больше вероятность, что другой код (браузер какой-нибудь) вытеснит контекст задачи и придется снова лезть в оператику.
@harry-smith404
@harry-smith404 28 дней назад
13:02 ну я так понимаю это из-за использования итераторов в for циклах в питоне на каком си c циклом for (int i = 0; i < 10; i ++) разрыв был бы может и меньше, но все равно бы был короч, любое телодвижение - это процессорное время любое телодвижение x10^(10) - это фатальное процессорное время
@xeqxeq4287
@xeqxeq4287 28 дней назад
Вот с Си не так всё очевидно. Если внутренний цикл поместится в кеш... Короче, надо конкретный случай смотреть и как оптимизирует компилятор(может вообще цикл развернуть)
@mikeofs1304
@mikeofs1304 28 дней назад
В данном случае что там что там будет разнится. потому что циклы это джампы(гоуту кому как нравится), а это лишняя операция не самая легкая
@harry-smith404
@harry-smith404 28 дней назад
@@xeqxeq4287 >Короче, надо конкретный случай смотреть это в любом языке, если ковыряться в этом, то надо разбираться, во что в итоге превращается исходный код
@dmitrymalina8272
@dmitrymalina8272 26 дней назад
Не подскажете, что за тема у вас в vim? На гитхабе лежит ваш старенький vim.rc с Oceanic-Next, а тут явно что-то покрасивше)
@t0digital
@t0digital 26 дней назад
gruvbox - хороша:)
@ABVGDE546
@ABVGDE546 28 дней назад
Я нубас, но коммент и лайк для продвижения. Ничего не пойму, но посмотрю
@alexusb9064
@alexusb9064 28 дней назад
модель клавиатуры подскажи плс.
@t0digital
@t0digital 28 дней назад
keychron k3
@idoodl
@idoodl 28 дней назад
31:09 я один заметил, что второй раз функция выдала -44% это как? Отрицательные значения мы понимаем, но каким образом при равном подходе (когда малый всегда значительно меньше большого) получилось отрицательное значение? (неужели где-то в кэше/еще чем-то происходит магия?) Вопрос без попытки в чем-то обвинить, просто рил не понял как такое произошло.
@t0digital
@t0digital 28 дней назад
Такие измерения всегда надо проводить на множестве запусков, чтобы как раз исключить такие флуктуации. Почему оно возникло - какие-то действия в системе возможно наложились. Работает много процессов, им ОС выделяет время, может что-то в этот момент более приоритетное запускалось в этот момент по мнению ОС и это привело к такому результату
@AlexanderBorshak
@AlexanderBorshak 28 дней назад
В том, что цикл несет накладные расходы, никто не спорит. В чем основной посыл - вложенный цикл с большим плечом ВНТУРИ медленнее вложенного с большим плечом снаружи. Верно? (Ну или наоборот - неважно.) Тогда предлагаю вам сделать такой эксперимент: меньшее плечо - 100, большее 1_000 (1 тысяча). Внутри самого внутреннего цикла какая-то емкая задача, скажем на 1 милисекунду - вызов CPU-bound функции, с подобранным временем примерно в 1мс, но всегда с одинаковыми данными, чтобы время работы не менялось. Теоретически прогон должен занять 100 * 1000 = 10_000 мс, то есть 10 секунд на саму работу ПЛЮС накладные расходы на циклы. Вот и сделать прогон для внешнего цикла с большим плечом, и с малым, и посмотреть, насколько разница в организации циклов будет влиять на результат, и будет ли она заметна вообще. А то еще окажется, что разница при изменении порядка циклов окажется 0,001% от всего времени работы программы, что делает усилия по такой оптимизации бессмысленными.
@t0digital
@t0digital 28 дней назад
Я говорю в тч об этом в видео.
@AlexanderBorshak
@AlexanderBorshak 28 дней назад
И если разница при таком тесте будет стремиться к нулю, то это - полагаю - и есть причина, по которой итерацией считают именно ЕДИНИЦУ РАБОТЫ, а не инициализацию и обновление счетчиков циклов. Затраты на инициализацию _в абсолютном большинстве случаев_ мизерны, и их просто не учитыват. В тех же случаях, когда они играют роль, обычно оптимизируют программу вплоть до ручного размещения памяти в регистрах - и это явно не случай Питона. Rust, C, Zig - да. Но не Питон, здесь это явная "экономия на спичках".
@t0digital
@t0digital 28 дней назад
@@AlexanderBorshak нет, не в абсолютном большинстве. 1 миллисекунда, о которой вы говорите - это до хрена даже для пайтон
@AlexanderBorshak
@AlexanderBorshak 28 дней назад
@@t0digital Скажем так: оптимизация с разворотом порядков цикла будет иметь смысл только в том случае, если время, затрачиваемое на инициализацию цикла сравнимо по времени с _единицей работы_ внутри этого цикла. Если разница будет уже на порядок (на единицу работы 10 нано-секунд, на инициализацию 1 нано-секунда, время взято с потолка), а тем более на порядки (100 к 1), то такая оптимизация уже теряет смысл. Намного лучше писать с учетом сложности алгоритмов - например, возможно, где-то использовав хеш-таблицу вместо массива (словарь вместо списка в терминах питона) мы сможем уменшить сложность алгоритма от квадратичной до линейной. Такая оптимизация намного важнее, чем попытка сэкономить 10 лишних наносекунд.
@mikeofs1304
@mikeofs1304 28 дней назад
@@AlexanderBorshak Раскажи как ты собрался, например в расте, размещать "память в регистрах".
@programisli
@programisli 28 дней назад
Твоя ошибка действительно в использовании слова итерации. Но в целом та ты прав. Если посмотреть на байт код, то циклы не бесплатные. 9-я и 10-я строки стоят сразу нескольких операций. Тело двух циклов выполняется 500 раз, но для того, чтобы выполнить 500 раз тело двух циклов в первом случае запуск двух циклов занял 600 раз - 10-я строка выполнялась 100 раз и 11-я выполнялась 500. Во втором случае запуск внешнего цикла происходил 5 раз, а внутреннего 500 раз. А глядя, во что превращается каждая из строк for, должно быть видно, на сколько получилась разница. Меньше запусков for приводит к экономии.
@Vorono4ka
@Vorono4ka 28 дней назад
Почему слово итерация не подходит? Как минимум каждый из циклов итерируется по range'у, это уже можно посчитать как итерации (как автор видео и сделал с помощью my_range), или в названии операции в байт-коде питона тоже ошибка?😂
@leonidgrishenkov4183
@leonidgrishenkov4183 26 дней назад
Картинка офигенная)
@t0digital
@t0digital 26 дней назад
Спасибо!
@plathardstuck28
@plathardstuck28 28 дней назад
если нужно использовать циклы в питоне - нужен не питон (c)
@Max-nr1bv
@Max-nr1bv 28 дней назад
Что что в названии написано? 😂
@t0digital
@t0digital 28 дней назад
Вся суть! База!
@PlayGameToday
@PlayGameToday 28 дней назад
Хорошо жить одному в просторном доме и заниматься программированием
@t0digital
@t0digital 28 дней назад
мне тоже нравится
@user-zl5sp9yh1n
@user-zl5sp9yh1n 28 дней назад
​@@t0digital А нам нравится добротный контент который получается в такой хорошей обстановке.
@PlayGameToday
@PlayGameToday 28 дней назад
@@t0digital Да, особенно хорошо, когда живешь один, нет жены, которая пилит. Молодец, я такой же.
@darkhekromant
@darkhekromant 27 дней назад
С итерациями все правильно, у каждого цикла свои итерации, почему они дожны объединяться? А если у тебя в одном цикле два вложенных разной длинны? Это сколько тогда у них в сумме итераций? :D
@finemechanic
@finemechanic 22 дня назад
Вот это разбор - просто до атомного уровня!
@user-gz4pi8ez5t
@user-gz4pi8ez5t 27 дней назад
Тоже несколько лет назад спорил. Мне доказывали, что копирование файла с индикатором прогресса выполняется быстрей, чем без него 😂😂😂😂
@t0digital
@t0digital 27 дней назад
А если отображение прогресса сделать в формате красивого на лету генерируемого 8к-видео с водопадом, птичками, листочками и мошками, чтоб комп просто визжал как сволочь - тогда файлы вообще копироваться мгновенно станут!
@user-fd7ce2em5y
@user-fd7ce2em5y 28 дней назад
Не хочу ставить лайк. Всего лайков 128. Что-то это да значит) Пусть значит. P.S.: Обновил страницу, чтобы всё таки поставить лайк. На этот раз лайков было уже 193)
@alexusb9064
@alexusb9064 28 дней назад
ну ассемблер это тоже не то что исполняется процессором. и никаких циклов вообще не существует, у проца все эти циклы это всегда какое то сравнение (CMP, TEST) и условный переход (JE JZ JNE JNZ...) байты этих команд можно поискать в IA32 Arch от intel, это и будут те самые байты которые проц выполняет. Ежу понятно что чем больше команд надо выполнить тем дольше работает программа, если внешний цикл меньше то как минимум команд сравнения будет выполнено меньше, а значит и работать будет быстрее, но процы умеет в предсказание переходов (привет SPECTRE и MELTWOWN и уже с нмни) и научились заренне исполнять код, так что это даже микро-оптимизацией наверное не стоит считать, скорее всего это вообще не особо актуально.
@t0digital
@t0digital 28 дней назад
Да, и об этом тоже есть в этом видео:)
@xeqxeq4287
@xeqxeq4287 28 дней назад
Вот его торкнуло 🤣🤣🤣 Мужик выдыхай!!! 😁😁😁
@AlexanderBorshak
@AlexanderBorshak 28 дней назад
)))
@Verdgil
@Verdgil 28 дней назад
А всё почему, а всё потому, что пайтон не очень оптимизирует, я сейчас вбил аналогичный код в C++, так вот он мне внутренние циклы просто свернул до умножения простого P.S. Писать то я всё равно продолжу на любимом питончике, но, конечно, его оптимизирующему компилятору до компилятора а-ля clang или gcc ой, как далеко
@t0digital
@t0digital 28 дней назад
В 3.13 вроде jit завезут:)
@Verdgil
@Verdgil 28 дней назад
​​@@t0digitalне ну jit это лишь первый шаг, сишные компилятор просто свернул код до умножения 5*100 в одном случае и 100*5 во втором P.S. clang 15, apple version, O3
@t0digital
@t0digital 28 дней назад
Да, Сишка есть Сишка
@Verdgil
@Verdgil 28 дней назад
​@@t0digitalи не поспоришь
@Verdgil
@Verdgil 28 дней назад
​@@t0digitalи не поспоришь... верим в развитие нашего любимого языка
@baloobear70
@baloobear70 28 дней назад
Фрикциями?
@t0digital
@t0digital 28 дней назад
Да!
@baloobear70
@baloobear70 28 дней назад
@@t0digital это не может не радовать, дорогие друзья 😃
@tulliolevichivita5130
@tulliolevichivita5130 27 дней назад
имхо выгода от такой оптимизации будет стремиться к нулю, если внутри цикла будет стоять что-нить cpu-bound
@t0digital
@t0digital 27 дней назад
Об этом есть в видео
@Vorono4ka
@Vorono4ka 28 дней назад
Жду новых комментариев о том, что опять кто-то не прав и вообще всё не так и сам Гвидо говорил, что... 😂
@t0digital
@t0digital 28 дней назад
Гвидо, молчи, Гвидо, не надо😂
@user-zl5sp9yh1n
@user-zl5sp9yh1n 28 дней назад
Тут на ютубе есть парень который принимает участие в разработке питона, может у него спросите?😂
@mikeofs1304
@mikeofs1304 28 дней назад
Все правильно раскидал, и пример нормальный. Дурачки предлагающие размыть тяжелой операцией внутри - сводят одну задачу к совершенно другой. А итерация в твоем контексте - это один джамп в машинном коде, все отсальное это уже из совершенно других контекстов. И унижение этих "философов от cs'" при помощи байткода считаю абсолютно правильным. ЛайГ. И кстати индусский пример таки - пример трейдофа скорости на памятью И то же дичайше поддерживаю его добавление в методических целях
@andreymironov8169
@andreymironov8169 28 дней назад
То есть питоновский FOR_ITER сводится в итоге к jump? Не увидел такого в видео. А тяжелая операция показывает, что оптимизация с малым и большим циклом бессмысленна, тем более в питоне, который вообще не про скорость 😊
@mikeofs1304
@mikeofs1304 28 дней назад
@@andreymironov8169 раскажи мне чем на уровне машинного кода можно реализовать цикл кроме джампа? Спойлер loop это тоже джамп. Тяжелая операция это вырожденный случай общего. Или ьы не понимаешь таких слов?
@andreymironov8169
@andreymironov8169 28 дней назад
@@mikeofs1304 где питон, а где машинный код?
@mikeofs1304
@mikeofs1304 28 дней назад
@@andreymironov8169 в компьютере оба
@andreymironov8169
@andreymironov8169 28 дней назад
​@@mikeofs1304уровень умника понятен... иди котиков посмотри, они тоже в компьютере
@junjul887
@junjul887 27 дней назад
Ахахахахаха
@s_ivanov179
@s_ivanov179 28 дней назад
34 минуты унижения адептов аптимызации в сфере веб технологий!
@olegssh6452
@olegssh6452 28 дней назад
все функции с операциями сложения больших чисел лучше компилировать на Cython например для цикла инкрементирующего count 222222222 раза результаты: Cython: 5.83939254283905e-07 Python: 7.961033541010693 Cython выполнился быстрее на 1_363_332_384.09%
Далее
Stray Kids "ATE" Trailer
02:42
Просмотров 1,9 млн
glos bibir cokelat
00:18
Просмотров 5 млн
I Built a SECRET Tree House in My Backyard!
26:09
Просмотров 7 млн
STM32 I2C ч.2 CMSIS
47:28
Просмотров 1,8 тыс.
28 Вложенные циклы Python
16:45
Просмотров 104 тыс.
Rust Functions Are Weird (But Be Glad)
19:52
Просмотров 127 тыс.
Stray Kids "ATE" Trailer
02:42
Просмотров 1,9 млн