Почему реализация JITted Python все еще медленная?
Я понимаю, почему накладные расходы на интерпретацию дороги, но почему реализации JITted Python (Psyco и PyPy) все еще намного медленнее, чем другие языки JIT, такие как С# и Java?
Изменить: я также понимаю, что все является объектом, динамическая типизация является дорогостоящей и т.д. Однако для функций, где типы могут быть выведены, я не уверен, почему это имеет значение.
Ответы
Ответ 1
Самый простой ответ заключается в том, что PyPy просто не так быстро, как горячая точка, и Psyco никогда не будет.
Написание разумного JIT - это долгий и утомительный процесс, и потребовалось, например, много лет для того, чтобы получить точную точку, где она находится (при большом финансировании). Чем сложнее и динамичнее язык, тем дольше это требуется. С яркой стороны у нас есть хорошие примеры того, как JIT для динамических языков могут быть очень быстрыми, возьмите LuaJIT для одного, который может бить C или JVM на многих примерах.
Однако есть хорошие новости: согласно центр скорости PyPy получил на 27% быстрее в среднем за последние 100 изменений, так что это произойдет в конечном счете.
Ответ 2
Люди уже указали технические детали, поэтому я добавлю еще один фактор: деньги.
В последние несколько лет Javascript VM (Google V8, Mozilla Tracemonkey и Jaegermonkey, Apple Nitro) значительно увеличили скорость для другого динамического языка. Это во многом обусловлено стремлением Google сделать веб-приложения более мощными. У Python просто нет большой компании, чтобы выиграть, сделав ее в 50 раз быстрее.
О, и интеграция с C-расширениями, такими как numpy, означает, что скорость редко критична для кода Python.
Ответ 3
Python - динамический язык .
Это означает, что большая часть работы, которую выполняют другие статические языки (например, С# и Java) во время компиляции, выполняется во время выполнения, что снижает производительность.
EDIT:
Более того, JIT-компилятор для динамического языка, такого как python, может выполнять гораздо меньше оптимизаций для кода, потому что он не может делать много предположений из-за динамичности кода.
например.
Динамическая типизация предотвращает предположения о типе полей/переменных/параметров..., поэтому любая оптимизация, связанная с этим, практически невозможна.
EDIT2:
просто уточнение:
когда я говорю время компиляции, я имею в виду также время компиляции JIT, потому что на самом деле JIT является компилятором.
Применяя это к моему первому предложению, получается, что Python может выполнять гораздо меньше работы во время JIT, чем С# или Java...
Ответ 4
Хороший вопрос. Я не могу дать вам полный ответ, но я думаю, что одной из причин является концепция "все объекты и объект может быть что угодно". В Java, если вы попробуете "1.getClass()", это не сработает, если вы не включите его сначала, явно или неявно. В Python он работает из коробки. Но объекты, безусловно, более тяжелы, чем примитивные типы, которые Python просто не имеют.
"Объект может быть что угодно" еще важнее. Если вы пишете "someobject.somefield" в Java, во время компиляции он знает, что именно "somefield" и генерирует код, который обращается к нему напрямую. Ну, есть, вероятно, некоторые трюки, чтобы обеспечить лучшую совместимость с двоичными файлами, но это не похоже на Python, где он фактически выполняет какой-то поиск словаря во время выполнения, чтобы выяснить, что именно является "некоторым полем" в данный момент, поскольку поля могут добавлять и удалять динамически.
Короче говоря, Python более мощный, но эта мощность имеет свои затраты.
Ответ 5
Вы не можете сравнивать динамические языки с статическими языками уровня предприятия. Sun потратила много денег на оптимизацию языка, VM и JIT. Microsoft также провела справедливую работу со своей виртуальной машиной.
Более интересно сравнить динамические языки jit'ed. Это что-то вроде JavaScript, которые позволяют google сделать свой V8 быстрее, чем PyPy и ruby 1.9 или это просто сумма денег, которую вы инвестируете?
Ответ 6
Я понимаю, почему интерпретация накладные расходы дороги...
Сравните эти реализации Python с не-JIT интерпретируемым режимом Java и снова задумайтесь над своим вопросом.
Ответ 7
В 2014 году вся проблема не так ясна. Google V8 JS-движок делает некоторые довольно тяжелые вещи, чтобы оптимизировать ад из js.
PyPy может быть намного быстрее, если будут доступны только достаточные деньги. Скорость выполнения Python в основном не имеет значения, поэтому никто не инвестирует в PyPy.
Это уже не технический вопрос. Посмотрите инструкцию Java InvokeDynamic. Конечно, эти вызовы стоят дороже в первый раз, когда их вызывают, но JVM может делать магические вещи, как только эти призывы начинают запускаться. То есть: JVM может делать предположения и может узнать о коде при его запуске. Если метод всегда возвращает int, возможно, что этот метод всегда возвращает int. На самом деле JVM делает гораздо больше.
В 2014 году это действительно не динамический, а статический с точки зрения производительности. Конечно, С++ всегда будет самым быстрым инструментом, но динамические языки с динамикой не являются "величинами" медленнее, как это было несколько лет назад.
Подождите еще несколько лет, я уверен, что статический анализ намного сильнее в 2016 году или в 2017 году. Сейчас есть несколько очень интересных исследовательских проектов.
В теории:
Вы можете в принципе вывести каждый тип, используя анализ статического типа, вы должны понимать , что код делает, прежде чем он это сделает. Это не невозможно.
Когда статический анализ становится более мощным, вам больше не нужна система статического типа. Все системы статического типа, даже haskell's, ограничивают количество правильных программ. Итак, по существу: если у вас есть анализатор, который может подтвердить правильность программы, анализируя ее гораздо более мощную, как систему статического типа, которая может действовать только в пределах границ. И в отношении повторного использования кода: ничто не может бить динамическую типизацию.
Есть несколько человек, которые скажут, что динамическое типирование плохо для больших приложений, но статический анализ , если становится более мощным, на самом деле у вас будет такая же или, может быть, гораздо более проверенная правильность, как система статического типа может когда-либо предложить. Конечно, статически типизированные языки также могут быть подвергнуты статическому анализу, но система статического типа будет бесполезной.
Итак, по существу: вот много, если я знаю. Но 10 лет назад люди бы посмеялись, если бы вы сказали им, что js становится настолько быстрым, что вы можете легко писать тяжелые приложения 3d opengl в нем.
Никогда не недооценивайте будущее.