Почему Python медленнее, чем Java, но быстрее, чем PHP [закрыто]

17

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

Эти тесты всегда показывают, что Python медленнее, чем Java, и быстрее, чем PHP, и мне интересно, почему это так.

  • Java, Python и PHP работают внутри виртуальной машины
  • Все три языка преобразуют свои программы в свои собственные байтовые коды, которые запускаются поверх операционной системы, поэтому ни один из них не работает изначально
  • И Java, и Python могут быть «скомпилированы» ( .pycдля Python), но __main__модуль для Python не скомпилирован

Python и PHP динамически типизированы, а Java статически - вот почему Java работает быстрее, и если да, пожалуйста, объясните, как это влияет на скорость.

И, даже если аргумент dynamic-vs-static верен, это не объясняет, почему PHP медленнее, чем Python - потому что оба являются динамическими языками.

Вы можете увидеть некоторые тесты здесь и здесь , и здесь

treecoder
источник
Что касается Python против PHP: это, скорее всего, вопрос качества реализации.
Чарльз Сальвия
8
@good_computer Большинство тестов сделаны очень плохо. Был еще один недавний (я не думаю, что вы связали), что большинство людей, которые просматривали его, жаловались, что язык, который он назвал «самым быстрым», просто имеет лучший оптимизированный код. Обычно это делается неосознанно кем-то, не знакомым с языками, которые в конечном итоге считаются «медленными», поэтому они не понимают, что пишут лучший код на тех, которые они считают «быстрыми».
Изката
@ good_computer Мне кажется, что вы что-то утверждаете, поскольку ваш вопрос включает в себя текст « Всегда эти тесты показывают, что Python медленнее, чем Java и быстрее, чем PHP » и « PHP медленнее, чем Python ». Если убрать эти цитаты и перефразировать вопрос, чтобы он не зависел от языка, его можно было бы вновь открыть.
Briddums
Этот вопрос действительно необъективен : (1) ссылаясь на неавторизованные тесты, проводимые на очень наивно неоптимизированном коде, написанном начинающими программистами на языках, которые они не осваивают (как рассмотрено в соответствующих ветках комментариев), и (2) основанных на заблуждениях о интерпретируемых / байт-кодах ( интерпретируются php / python, байтовые коды java, файлы кеша python являются абстрактными синтаксическими деревьями, а не байт-кодом) и состоянием трех языков (существуют скомпилированные версии как python, так и php - python более зрелые, скомпилированные php, тем не менее, запускает Facebook)
ZJR

Ответы:

26

Код JVM может быть эффективно скомпилирован с использованием JIT с использованием тривиального (и быстрого) специального компилятора. Но то же самое было бы исключительно сложно для PHP и Python из-за их динамически типизированной природы. JVM преобразуется в довольно простой и понятный нативный код, очень похожий на то, что создавал бы компилятор C ++, но для динамических языков вам пришлось бы генерировать динамическую диспетчеризацию буквально для всех основных операций и для всех вызовов методов. Эта динамическая отправка является основным узким местом для всех языков такого рода.

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

Что касается разницы между Python и PHP, то последний имеет гораздо более низкое качество. Теоретически он может работать быстрее, но никогда не будет.

SK-логика
источник
1
Почему JIT «исключительно» сложен для динамических языков? Посмотрите на v8 или TraceMonkey в мире JavaScript - там JIT работает просто отлично.
Treecoder
6
@ хороший_компьютер, отслеживание JIT заметно сложнее, чем обычно, специальные JIT, и они все еще работают намного медленнее, чем JIT для статически типизированных языков. Правильная трассировка JIT подразумевает полноценную абстрактную интерпретацию, и она будет подавлять каждый evalвызов.
SK-logic
2
Вероятно, около сотни инженеров в команде компилятора Oracle HotSpot не согласны с «тривиальной» частью :-)
Йорг Миттаг
1
@ JörgWMittag, конечно, HotSpot не так прост, он немного статичен, он использует результаты профилирования во время выполнения, но все же он намного проще, чем правильная трассировка JIT. И, я бы сказал, HotSpot слишком сложен, и его реализация, мягко говоря, слишком многословна.
SK-logic
1
@Frank Shearar, специальный JIT для динамического языка, такой же тривиальный, как и для статически типизированного (см., Например, LuaJIT). ОТО, эффективный JIT - это совсем другое.
SK-logic
21

Есть общая проблема с этим вопросом в том, что он слишком абсолютен. Не имеет смысла говорить «язык X быстрее, чем язык Y». Компьютерный язык сам по себе не является «быстрым» или «медленным», потому что это всего лишь способ выражения алгоритма. Фактический вопрос должен быть примерно таким: «Почему реализация X1 языка X быстрее, чем реализация Y1 языка Y для этой конкретной проблемной области?»

Некоторые различия в скорости, безусловно, будут выпадать из самого языка, поскольку некоторые языки легче реализовать в одних доменах, чем в других. Но многое из того, что делает реализацию быстрой, - это не язык. Например, вы не можете сказать «Python медленнее, чем Java», не задумываясь о том, говорите ли вы о CPython, IronPython или PyPy. Это особенно верно для языков, которые используют виртуальную машину, поскольку скорость будет напрямую зависеть от качества виртуальной машины.

Кроме того, я работаю с системой, которая по разным причинам не может использовать JIT на нашем устройстве с очень популярной виртуальной машиной JavaScript, которая обычно поддерживает ее. Это означает, что наш JavaScript работает намного медленнее, чем на ПК с аналогичным процессором. Это одно изменение, которое напрямую не связано с самим языком, превращает JavaScript из «в несколько раз медленнее, чем С ++» в «на несколько порядков медленнее, чем С ++», для задач, которые нас интересуют.

Также следует учитывать, что языки отличаются по характеристикам производительности способами, которые не могут быть напрямую сопоставлены. Слишком много тестов просто переводят программу с языка A на язык B и не учитывают, что языки отличаются быстродействием. (Вы можете увидеть это в любом разумном сравнительном тесте, таком как те, на которые вы ссылаетесь, поскольку они часто имеют примечания типа «спасибо тем-то за то, что показали мне, как реализовать это на языке Foo».)

Например, возьмите этот код Java:

for(int i=0;i<10;i++) {
    Object o = new Object;
    doSomething(o);
}

Было бы заманчиво «переписать» это в C ++ и сравнить время выполнения:

for(int i=0;i<10;i++) {
    Object *o = new Object;
    doSomething(o);
    delete(o);
}

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

for(int i=0;i<10;i++) {
    Object o;
    doSomething(&o);
}

Дело не в том, что C ++ может быть быстрым, а в том, что написание тестов для сравнения языков действительно очень сложно. Чтобы сделать это соответствующим образом, вы должны быть экспертом в обоих языках и писать с нуля на обоих языках. Даже тогда вы можете легко столкнуться с областями, в которых один язык превосходит определенную задачу. Например, я могу написать версию Towers of Hanoi на C ++, которая будет работать быстрее, чем Java на любом приемлемом компиляторе. Я могу сделать это путем читерства, используя шаблоны C ++, оцененные во время компиляции (http://forums.devshed.com/c-programming-42/c-towers-of-hanoi-using-templates-424148.html)

Дело не в том, что я мог бы сказать, что «C ++ быстрее, чем Java», потому что моя программа возвратилась мгновенно, в то время как версия Java работала в течение нескольких минут (и надеялась, что никто не заметил, что моя программа собиралась за полчаса). Дело в том, что для этого В узком случае C ++ быстрее. Для других узких случаев это может быть наоборот. Таким образом, это не «C ++ быстрее», а «C ++ быстрее в тех случаях, когда вы можете оценить выражение во время сборки, используя шаблоны». Менее удовлетворительно, но верно.

Различия в скорости в языках в основном связаны с реализацией. Скомпилированные языки будут работать быстрее, чем интерпретируемые. Компиляция в нативный код будет быстрее, чем в байт-код. Это будет иметь гораздо больший эффект, чем такие вопросы, как статический тип языка или нет. И, конечно, хорошие реализации будут быстрее, чем плохие.

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

Горт Робот
источник
6

Это связано с качеством компилятора, компилятор java постоянно оптимизируется гораздо дольше, а оптимизация важнее, потому что весь код скомпилирован для Java. Я не уверен, что точная причина для Python быть быстрее, чем PHP, но я бы поспорил из-за влияния Google с Python.

Ryathal
источник
8
Почему это было отвергнуто? Это точно ответ: производительность чисто предмет научных исследований и инженерных усилий, и , таким образом , в конечном счете , деньги. Компании, которые производят Java-реализации, оказываются богаче, чем компании, производящие Python или PHP-реализации. Это все.
Йорг Миттаг
1
Кроме того, я почти уверен, что оптимизации CPython не будут приняты, если они делают код слишком трудным для чтения и лишь незначительно повышают производительность.
cgt
2
+ Йорг Миттаг: Я не согласен. Некоторые языковые функции могут быть очень сложными для реализации с точки зрения производительности, поэтому они делают создание эффективной реализации очень трудным или почти невозможным. С другой стороны, легко создать «эффективную» реализацию языка «Ассемблер».
user281377
@ammoQ Я подозреваю, что многое из этого сводится к системам типов и, в частности, к способности точно знать, какой у вас тип, и какова точная семантика допустимых операций. Динамические языки приобретают гибкость по своей природе, но затрудняют проверку типов (и, следовательно, компиляцию в безопасный гипер-быстрый код).
Donal Fellows
1
@DonalFellows Точно моя мысль. Чем меньше известно во время компиляции, тем больше нужно выяснить во время выполнения.
user281377
4

Почему Java самая быстрая:

Статически типизированный + JIT compile + --server флаг для агрессивной перекомпиляции исполняемого кода.

Почему Python быстрее чем PHP:

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

Почему PHP отстой:

Это в основном javascript на сервере (без поддержки многопоточности, полностью динамический, свободно типизированный).

По сути, чем больше компилятор знает о вашем коде, тем больше он может оптимизировать. Java полностью оптимизируется перед запуском и во время работы. Python оптимизируем во время работы, а PHP ужасен. Facebook фактически передает их PHP на C, прежде чем он попадет на сервер.
https://developers.facebook.com/blog/post/2010/02/02/hiphop-for-php--move-fast/

Ajax
источник
На самом деле javascript на сервере - это Node.JS, и, насколько я понимаю (хотя я не буду это доказывать), движок V8 в целом превосходит PHP (хотя, вероятно, и не на тонну). Кроме того, вы должны упомянуть, что Python может быть скомпилирован на нативный (Как он работает по сравнению с Java тогда?)
Джимми Хоффа
Я не использовал Python достаточно широко, чтобы помочь вам в этом, но я могу сказать, что nodejs под управлением V8 имеет поддержку собственных расширений C (хотя пересечение границы JS / C предположительно медленное), плюс он может использовать JIT-компилятор Google. .. Я не удивлюсь, если узел будет быстрее, чем Python и PHP. Вот тест (как и большинство других ошибок ) blog.famzah.net/2010/07/01/… Обратите внимание, что Java выглядел медленнее, чем JS, пока комментатор не указал на наши недостатки в тесте ... Итак, возьмем его с зерном поваренная соль. :)
Аякс
Тем не менее, node и php также являются однопоточными, и если вы не хотите настраивать прокси кластера (например, haproxy), я бы не стал касаться ни одного из них в серьезной производственной среде.
Аякс
1

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

Неудивительно, что Python довольно хорош в сложной математике, если учесть, где и почему он был впервые написан .

PHP, с другой стороны, был написан для обслуживания веб-страниц, он может делать другие вещи, но веб-страницы - это то, что лучше всего, и наравне или лучше, чем Java в этой задаче.

Джеймс Андерсон
источник