Обновить

Мифы и легенды о производительности Python

Уровень сложностиСредний
Время на прочтение10 мин
Количество просмотров23K
Всего голосов 43: ↑39 и ↓4+56
Комментарии58

Комментарии 58

Принцип Парето гласит, что 80% времени тратится на 20% кода, поэтому оптимизация этих 20% должна помочь.

Разве принцип Парето говорит не об обратном? 80% кода на 20% времени. Или в программировании он действует по другому?

Да, я понимаю, что это не столь важно в рамках контекста статьи, но всё равно, просто любопытно

Так он вообще не про "20% чего взять чтобы 80% результата получить", как его впаривать любят. Он про постериорное наблюдение, то есть "после того как сделали 100% и пересчитали что к чему, оказалось что...". А ещё там исходно нет где же эти заветные 20% искать, потому что такой цели и не было никогда.

А то, что в статье - это не закон Парето(который не закон) - это анализ производительности, поиск узких мест и их опитимизация. Штука нужна, полезная, правильная. Но не Парето.

Понял, спасибо!

НЛО прилетело и опубликовало эту надпись здесь

Обратный принцип Паретто)

Одно следует из другого. И наоборот.

принцип Парето это просто такое наблюдение что соотношение чего-то более полезного к менее полезному обычно распределяется как примерно 80/20, мне кажется что можно это интерпретировать как угодно... например, то что наиболее используемые функции это примерно 20% от программы и их имеет смысл оптимизировать... или например что 20% всех функций быстрые потому что их уже оптимизировали а остальные 80 либо редко используются либо чтобы их оптимизировать нужно будет уже затратить 80% работы... наверное так

Динамические возможности в 99% не нужны, но оставшийся 1% и делает Python столь потрясающим.

Почему бы не сделать некое объявление в языке, что данный код не использует динамические черты и тогда интерпретатор, JIT и ран-тайм смогут делать всё гораздо быстрее. Или наоборот, по умолчанию (для 99%) будет статика, а когда нужна динамика, надо явно это указать в коде.

Обычно при компиляции динамических языков так и делают.

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

В Java сделано иначе (хоть и для других целей).

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

Но JIT ведёт статистику, и если в какой-то метод приходит (почти) только одна имплементация (или две, для двух тоже есть оптимизация) - JIT поставит специальную ловушку на случай "а что если нет", в которой проводит деоптимизацию (на самом деле не совсем так, но в первом приближении пойдет). Для нормального же случая код будет работать так, будто был объявлен конкретный класс, вызовы будет дозволено инлайнить и проводить все возможные оптимизации.

Теоретически, для питона никто не мешает делать так же. На практике же JIT питона просто находится в совершенно зачаточном состоянии.

Да, возможно. Но если интерфейсы в Java применяются чуть больше, чем везде, и есть смысл написать очень умный оптимизатор, то динамические черты Python применяются ну очень редко. Поэтому в качестве быстрого и простого решения - явное объявление, в исходнике, если будешь использовать динамику.

Это бессмысленно. Для любого эффективного JIT нужно считать статистику. Если вы уже имеете на руках статистику - поставить trap для редких случаев тривиально. Инлайн всё равно нужно уметь делать, иначе всё будет медленно, т.к. именно инлайн открывает пути к другим оптимизациям (убрать дублирующиеся проверки, выкинуть аллокацию неиспользуемых объектов, разложить по стеку то, что не убегает за пределы скоупа и т.д.). Хотите чтобы работало быстро - нужен нормальный JIT. Иначе всё мёртвому припарки.

Тем не менее. Классический неоптимизирующий компилятор должен, по идее, хотя бы удесятерять скорость. А текущий вариант питоновского JIT-а лишь удваивают, да и то лишь в некоторых удачных случаях. Так что тут есть, что делать, во всех направлениях.

Не уверен, откуда цифры про удесетирять, и не уверен в её правомерности. Впрочем, интерпретатор питона тоже довольно примитивен в сравнении, например, с джавовым.

Насколько я понимаю, аналог этого описан в PEP 659 – Specializing Adaptive Interpreter | peps.python.org и реализован с 3.11. В терминах CPython это еще не JIT, работы по JIT-у только ведутся.

Для питона шаг наверное очень правильный, но всё равно звучит слабенько. Да, can benefit without JIT, но без возможности убер-оптимизаций связанных с инлайном, питон всё равно будет оставаться неприлично медленным.

Понятно, что JIT в той же Java не ограничен специализаций. И специализация это был (насколько я понимаю) один из шагов в направлении ускорения вычислений в CPython, без радикального изменения интерпретатора. В faster-cpython/ideas вроде был описан переход от специализации к JIT. Но в CPython катастрофически не хватает а) рук, б) понимающих людей. Сейчас над ним работают, наверное, не больше 5 человек. А с учетом того, что MS фактически прикрыл проект по оптимизации, то в целом все довольно грустно.

Если есть желание и возможности поучаствовать в развитии JIT в питоне - то все возможно. Можно также присоединиться к чату https://t.me/opensource_findings_chat - пара CPython Core dev там обитает.

Нет, спасибо, я напротив считаю, что питон не нужон и должен умереть)

Жаль только мир считает иначе)

Тем более присоединяйтесь, будете разваливать его изнутри, так сказать :)

Самый большой миф тут тот, что язык в честь питона змеи назвали. На самом деле была такая группа Monty Python , вот в честь нее язык и назвали.

А название этой комик-группы произошло от обычного слова, означающего "питон". И это слово как означало змею (питона), так и означает. И логотип этого языка содержит изображение змеи. Так что хватит поднимать эту глупую тему

А название змеи произошло от греческого слова Pytho (Πυθώ). И так раньше назывался город Дельфи. Так что язык питон так назван в честь языка дельфи!

Можно начинать писать статью с заголовком: Дельфи и Питон - как древние греки предвосхитили программирование в античности.

Так что язык питон так назван в честь языка дельфи!

"Пифон был чудовищным змеем, порожденным Геей, землей, и посланным Герой (женой Зевса) для преследования Летой, беременной от Зевса. Аполлон, сын Лето, убил Пифона, чтобы отомстить за свою мать и занять Дельфийский оракул. По имени Пифона была названа Пифия, жрица-прорицательница в Дельфах."

И всё же змей, как ни крути.

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

Если бы про мужиков, то было бы Python Ball(s)

Все вот говорят, что память дешева.

Но почему-то уже не в первом проекте в крупном бизнесе на продакшене девопс даёт тебе только 2Гб на под. Ну если долго просить через СТО то расщедрится на 4 Гб. Ну и соответственно привет батчи, целые дни работы над оптимизацией и тд.

У памяти есть такая бяка, что её скорость и размер накрепко связаны между собой. Это например причина, почему у массовых GPU видеопамяти сейчас только 2 размера: 8 и 16. В десктопных компах сегодня на полной скорости можно поставить только 64Гб памяти. Если поставить больше, начнутся ощутимые провалы по скорости. У серверных наверняка лучше, но всё равно пиз предел близок.

"В десктопных компах сегодня на полной скорости можно поставить только 64Гб памяти"

И это проблема только у ддр5 (и по большей части у амд), тогда как у ддр4 такого не было. Так что мимо.

Память очень дешевая. Если сравнивать ее с оплатой труда программиста, то это просто копейки. Если вы арендуете память, то наверное будут экономить. Но если у вас свои сервера, то гораздо дешевле накинуть практически сколько угодно памяти.

«Если вы считаете Python медленным или недостаточно быстрым, поднимите руку»; поднялось много рук, в отличие от презентации на PyCon Italy, где руку не поднял почти никто из присутствующих. «Совершенно другая аудитория», — сказал он с улыбкой.

Другая аудитория, но не по части знания мифов, а по культуре дискуссии. Итальянский айтишник не будет публично негативно высказываться по адресу других айтишников. А постсоветские - легко, их спросили - они и ответили что знали.

Ну фактически, из статьи получается, что - проблемы производительности питона в том, что это питон и в его дизайне и философии. (Как в принципе и у любого динамического языка).

Проблема скорее что из этих языков пытаются сделать универсальную тулзу и начинают лепить костыли — тайпхинты и тайпскрипты.

Короче в воздухе витает дух статически типизированного интерпретируемого языка... (Очередного)

А потом будут добавлять в него динамические фишки...

Кмк это лучше, чем в динамику докидывать статику, которая там не пришей.

Производительность в Питоне - это миф и легенда ;-)

Однако статическая типизация не применяется принудительно в среде выполнения

Type hints - это не статическая типизация. Поэтому и не применяется. Это информация для линтеров разнообразных, интерпретатор и runtime про нее знать не знают.

Вижу два варианта:

  • LLM переводила

  • LLM сочиняла

Там в оригинале написано. Не вижу проблемы, хинты содержат исчерпывающую информацию о типе.

Ее вполне можно дергать в рантайме.

Pydantic вполне использует ее в рантайме.

Python: грузит данные в GPU
GPU: считает
Python: во, смотрите, как я быстро посчитал!

      Ваня (в кучерском армячке).
Папаша! кто строил эту дорогу?
      Папаша (в пальто на красной подкладке).
Граф Петр Андреевич Клейнмихель, душенька!
Разговор в вагоне

(с) Н.А, Некрасов, Железная дорога, предисловие

У меня был случай год назад: имеется почти 100 тысяч png картинок, для последующей обработки их нужно ресайзить, попутно выдирая информацию из тегов и складывая ее в отдельный текстовый файл. Сначала попробовал накидать скрипт для Graphick Magick - 4 картинки в секунду. Маловато. Для сравнения попробовал скормить их FS Viewer-у, берет батчем по 5 картинок и думает над ними секунды две. Ну и уже от отчаяния решил попросить ЛЛМ написать питоническую программу с нужным функционалом. 20 картинок в секунду. И это на одном ядре cpu без многопоточности. Черт его знает как оно так у него под капотом считается, но я реально офигел. Хотя во всех трех случаях с картинкой нужно было проделать всего пару операций - ресайзить (с сохранением результата в отдельной папке) и выдрать теги (у FS viever нет такого функционала). Через ту библиотеку как оказалось можно с картинками проделывать практически все то же самое, что и в GM, только сильно быстрее.

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

As is true for modules, classes partake of the dynamic nature of Python: they are created at runtime, and can be modified further after creation.

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

Другой вопрос, кому это может быть нужно и как это может вписаться даже в самые всратые и кривые практики и стандарты. Но видимо кому-то нужно. 99% это не нужно, даже если они так считают - надо дать им по башке и объяснить, что не нужно.

Но проблему это не устранит, это суть языка. Куча всего построена вокруг этого. Это как поставить автомобиль на рельсы, оставить все органы управления и претендовать, что это тепловоз. Универсально, но и не рыба не мясо.

Те проекты, что я видел в продакшоне, не используют динамичность больше, чем условный std:: variant в плюсах, они наоборот пытаются использовать костыли для внедрения статической типизации. Прикол какой-то: брать динамический язык и делать его статическим))

Потому что то, что мы считаем ошибкой, правила языка не считают таковой. Утиная типизация, ё-моё. А, да, и ещё проблема давно решена: есть mypy, есть Pydantic, и есть грамотный code style.

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

Вот здесь и в этом, и в прошлом, и позапрошлом году, и кучу лет подряд Питоха лидирует: https://www.tiobe.com/tiobe-index/
Вывод: Проблема производительности питона надуманна...

Вывод: хуже бредовых рейтингов только те, кто их читает.

Ммм. Мы живем в симуляции и куча НПС просто так не осознано юзает питоху и гонит рейтинги, неуклонно и методично из года в год. Здравый смысл в том, что проблема производительности питона надуманна. Если бы она была и мешала, то никто бы его не юзал. Видимо плюсы перекрывают не существенные минусы...

self.name = name

скорее всего это будет плохо работать (в плане локальности данных) даже в "супер быстрых" языках типа C++

потому что name это что-то типа std::string и непосредственно за стороковыми данными нужно ходить по указателю в какое-то случайное место в куче

обсуждать производительность питона не упоминая GIL ? знаем, умеем, практикуем.

Окей, производительность однопоточного питона. По-моему, самое интересное именно тут. В особенности большие списки примеров, которые показывают, как сложно компилировать питон (это мне доставляет такое же удовольствие, как и книга "контрпримеры в анализе").

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

В Питоне есть и потоки и процессы (в обход GIL на разных ядрах) и прямой доступ к памяти (SharedMemory). В крупномасштабном проекте интерпретатор простаивает больше в ожиданиях завершения файловых и сетевых операций. Нету проблем производительности в питоне, от слова СОВСЕМ.

Есть у Питона проблемы с производительностью. Достаточно сравнить в цикле простые математические операции с другим языком. И речь тут не о потоках, которым GIL мешает.

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

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

А это тут вообще не при чем. Это никак не касается вопроса производительности языка.

Вы путаете проблему производительности со скоростью выполнения синтетических тестов. Я утверждаю, что на практике, - нет проблемы производительности языка, что она надуманна и не стоит обсуждения. Никому эти синтетические тесты не нужны (чё бы тогда не сравнивать с ассемблером, и говорить что у C++ есть проблемы производительности??)
Я говорю что проблемы производительности при практическом использовании питона нету или она не существенна.
Еще раз. вот доказательство моих слов: https://www.tiobe.com/tiobe-index/

Вы путаете проблему производительности со скоростью выполнения синтетических тестов.

Синтетические тесты и показывают номинальную производительность.

Я утверждаю, что на практике, - нет проблемы производительности языка, что она надуманна и не стоит обсуждения.

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

Никому эти синтетические тесты не нужны (чё бы тогда не сравнивать с ассемблером, и говорить что у C++ есть проблемы производительности??)

Сравниваются языки одного уровня. И Питон и С++ - языки высокого уровня. Ассемблер - нет.

Я говорю что проблемы производительности при практическом использовании питона нету или она не существенна.

Элементарные математические операции, операции требующие работы с памятью в Питоне гораздо медленнее, чем в других языках. Это сказывается не на разовой операции, а на производительности в целом. Если С++ делает расчеты (за 1 сек), а затем делает запрос в БД (3 сек) и на сервер (2 сек), то тратит на это 6 секунд работы, в то время как Питон при тех же значениях запроса к БД и серверу потратит больше времени из-за первого шага с расчетами. И не имеет значения сколько времени тратится на внешние операции, они и там и там одинаковы, важен код именно на самом языке.

Вы уверены, что Питон обрабатывает так же быстро большой JSON файл, как и C++? Или может так же быстро генерирует его? Ответ - нет. Скорость работы с базовыми операциями (работа со строками, математикой, памятью) - это важные вещи и в Питон эти операции выполняются дольше, чем в других языках.

Ну да, конечно. У нас тут один внутренний сервис переписали с python на плюсы. Получили ускорение ответа x10

Антонио сказал, Антонио писал...
Слишком много частностей

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
ruvds.com
Дата регистрации
Дата основания
Численность
11–30 человек
Местоположение
Россия
Представитель
ruvds