Какие семантические особенности Python (и других динамических языков) способствуют его медлительности?
Никто.
Выполнение языковых реализаций зависит от денег, ресурсов и кандидатских диссертаций, а не от особенностей языка. само намного более динамичен, чем Smalltalk, и немного более динамичен, чем Python, Ruby, ECMAScript или Lua, и имеет виртуальную машину, которая превосходит все существующие виртуальные машины Lisp и Smalltalk (на самом деле дистрибутив Self поставляется с небольшим интерпретатором Smalltalk, написанным на Self и даже это было быстрее, чем большинство существующих виртуальных машин Smalltalk), и было конкурентоспособным, а иногда даже быстрее, чем реализации C ++ того времени.
Затем Sun прекратила финансирование Self, а IBM, Microsoft, Intel и Co. начали финансировать C ++, и эта тенденция изменилась. Разработчики Self покинули Sun, чтобы основать свою собственную компанию, где они использовали технологию, разработанную для Self VM, для создания одной из самых быстрых виртуальных машин Smalltalk (Animorphic VM), а затем Sun выкупила эту компанию и слегка измененную версию. эта Smalltalk VM теперь более известна под названием «HotSpot JVM». По иронии судьбы, программисты Java смотрят на динамические языки свысока как на «медленные», хотя на самом деле Javaбыл медленным, пока не принял технологию динамического языка. (Да, верно: JSM HotSpot по сути является виртуальной машиной Smalltalk. Верификатор байт-кода выполняет большую проверку типов, но как только байт-код принят верификатором, ВМ, и особенно оптимизатор и JIT, на самом деле этого не делают. большой интерес со статическими типами!)
CPython просто не делает много вещей, которые делают динамические языки (или, скорее, динамическую диспетчеризацию) быстрыми: динамическая компиляция (JIT), динамическая оптимизация, умозрительная вставка, адаптивная оптимизация, динамическая де-оптимизация, обратная связь / вывод динамического типа. Есть также проблема в том, что почти все ядро и стандартная библиотека написаны на C, что означает, что даже если вы вдруг сделаете Python 100x быстрее, это вам не сильно поможет, потому что что-то вроде 95% кода, выполняемого Программа на Python - это C, а не Python. Если бы все было написано на Python, даже умеренное ускорение привело бы к лавинному эффекту, когда алгоритмы становятся быстрее, а базовые структуры данных - быстрее, но, конечно, основные структуры данных также используются в алгоритмах, а также основные алгоритмы и основные данные. структуры используются везде,
Есть несколько вещей, которые заведомо плохи для ОО-языков с управлением памятью (динамических или нет) в современных системах. Виртуальная память и защита памяти могут быть причиной снижения производительности сборки мусора в частности и производительности системы в целом. И в языке, безопасном для памяти, это совершенно не нужно: зачем защищать от недопустимых обращений к памяти, если в языке нет доступа к памяти с самого начала? Azul решил использовать современные мощные MMU (Intel Nehalem и новее и эквивалент AMD), чтобы помочь сборке мусора вместо того, чтобы препятствовать ему, но даже несмотря на то, что он поддерживается процессором, современные подсистемы памяти основных ОС недостаточно мощны чтобы разрешить это (именно поэтому виртуальная машина Azul работает виртуально на голом металле, кроме ОС, не в ней).
В проекте ОС Singularity Microsoft измерила влияние ~ 30% на производительность системы при использовании защиты MMU вместо системы типов для разделения процессов.
Еще одна вещь, которую заметил Азул при создании своих специализированных процессоров Java, заключалась в том, что современные основные процессоры сосредотачиваются на совершенно неправильных вещах, пытаясь снизить стоимость промахов кэша: они пытаются уменьшить количество промахов кэша с помощью таких вещей, как прогнозирование ветвлений, предварительная выборка памяти, и так далее. Но в сильно полиморфной ОО-программе шаблоны доступа в основном псевдослучайные, предсказать просто нечего. Итак, все эти транзисторы просто потрачены впустую, и вместо этого нужно снизить стоимость каждого отдельного промаха кеша. (Общая стоимость равна #misses * cost, основной поток пытается прекратить работу первого, Azul - второго.) Java Compute Accelerator от Azul может иметь 20000 одновременных промахов кэша в полете и все же добиться прогресса.
Когда Azul начал, они подумали, что возьмут некоторые готовые компоненты ввода / вывода и спроектируют свое собственное специализированное ядро ЦП, но то, что им действительно нужно было сделать, было с точностью до наоборот: они взяли довольно стандартную готовую версию. полка 3-адресное ядро RISC и разработали собственный контроллер памяти, MMU и подсистему кеша.
tl; dr : «медлительность» Python является не свойством языка, а а) его наивной (основной) реализацией и б) тем фактом, что современные ЦП и ОС специально разработаны для обеспечения быстрой работы С, а также функции, которые они иметь для C либо не помогает (кеш) или даже активно ухудшает (виртуальная память) производительность Python.
И вы можете вставить практически любой управляемый памятью язык с динамическим специальным полиморфизмом здесь ... когда дело доходит до задач эффективной реализации, даже Python и Java в значительной степени "один и тот же язык".