Чому Python повільніше Java, але швидше, ніж PHP [закрито]


17

Я багато разів бачив різні орієнтири, які показують, як виконується купа мов у тому чи іншому завданні.

Ці орієнтири завжди виявляють, що Python повільніше, ніж Java, і швидше, ніж PHP, і мені цікаво, чому це так.

  • Java, Python та PHP працюють у віртуальній машині
  • Усі три мови конвертують свої програми у власні байтові коди, які працюють над ОС - так що жодна не працює заново
  • І Java, і Python можна "компілювати" ( .pycдля Python), але __main__модуль для Python не компілюється

Python та PHP динамічно набираються, а Java статично - це причина Java швидше, і якщо так, то, будь ласка, поясніть, як це впливає на швидкість.

І навіть якщо аргумент "динамічний vs-статичний" є правильним, це не пояснює, чому PHP повільніше, ніж Python - тому що обидва є динамічними мовами.

Ви можете побачити деякі орієнтири тут і тут , і тут


Щодо Python vs. PHP: це, швидше за все, питання якості впровадження.
Чарльз Сальвія

8
@good_computer Більшість орієнтирів дуже погано зроблені. Був ще один останній (я не думаю, що ви пов’язали), що більшість людей, які переглядали його, скаржилися, що мова, на яку вона стверджується як "найшвидша", просто має найкращий оптимізований код. Зазвичай це робиться несвідомо тим, хто не так добре знайомий з мовами, які в кінцевому підсумку вважаються "повільними", тому вони не розуміють, що вони пишуть кращий код у тих, які вони виявили "швидкими".
Ізката

@good_computer Мені здається, що ти щось вимагаєш, оскільки у твоє запитання входить текст " Завжди ці орієнтири виявляють, що Python повільніше, ніж Java, і швидше, ніж PHP " і " PHP повільніше, ніж Python ". Якщо видалити цитати та перефразовувати це питання як мовний агностик, це може відновити його.
briddums

Це питання справді необ'єктивне : (1) посилаючись на неавторитетні орієнтири, що проводяться на дуже наївно неоптимізованому коді, написаному початківцями програмістами мовами, які вони не опановують (як розкрито у відповідних нитках коментарів) та (2), побудованими на помилках про інтерпретовані / байт-кодові мови ( інтерпретуються php / python, файли Java-bytecoded, файли кеша python - абстрактні синтаксичні дерева, а не байт-код) та стан трьох мов (є компільовані версії як python, так і php - python's більш зрілі, складені php, правда, працює у фейсбуці)
ZJR

Відповіді:


26

Код JVM можна ефективно компілювати JIT, використовуючи тривіальний (і швидкий) спеціальний компілятор. Але те саме було б надзвичайно важким для PHP та Python через їх динамічно типізований характер. JVM перекладається на досить низький і простий нативний код, досить схожий на те, що створює компілятор C ++, але для динамічних мов вам доведеться генерувати динамічну розсилку буквально для всіх основних операцій та для всіх викликів методу. Ця динамічна відправка є основним вузьким місцем для всіх подібних мов.

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

Що стосується різниці між Python та PHP, то останній лише значно нижчої якості. Теоретично він міг би бігти швидше, але це ніколи не буде.


1
Чому JIT "виключно" важкий для динамічних мов? Подивіться на v8 або TraceMonkey у світі JavaScript - там JIT працює чудово.
treecoder

6
@good_computer, трасування JIT значно складніше, ніж звичайні, спеціальні JIT, і вони все ще працюють набагато повільніше, ніж JIT для статично набраних мов. Належне відстеження JIT передбачало б повну абстрактну інтерпретацію, і воно задушилось би на кожному evalдзвінку.
SK-логіка

2
Мабуть, близько сотні інженерів в команді-компіляторі HotSpot Oracle, яка не погодиться з приводу "тривіальної" частини :-)
Jörg W Mittag

1
@ JörgWMittag, звичайно, HotSpot не такий простий, він робить трохи статичного аналізу, використовує результати профілювання часу виконання, але все-таки це набагато простіше, ніж правильний трасування JIT. І, я б сказав, HotSpot є надскладним, і його реалізація є, кажучи ввічливо, трохи надто багатослівною.
SK-логіка

1
@Frank Shearar, спеціальний JIT для динамічної мови настільки тривіальний, як і для статично набраного (див., Наприклад, LuaJIT). ОТО, ефективний JIT - це зовсім інша річ.
SK-логіка

21

У цьому питанні є загальна проблема в тому, що вона занадто абсолютна. Насправді немає сенсу говорити "мова X швидша за мову Y". Мова комп'ютера сама по собі не є "швидкою" чи "повільною", оскільки це лише спосіб вираження алгоритму. Справжнє питання повинно бути чимось порядком "чому реалізація X1 мови X швидша, ніж реалізація Y1 мови Y для цієї конкретної проблемної області?"

Деякі відмінності у швидкості, безумовно, випадуть із самої мови, оскільки певні мови легше реалізувати певні домени, ніж інші. Але багато з того, що робить імплементацію швидкою, - це не мова. Наприклад, ви дійсно не можете сказати, що "Python повільніше, ніж Java", не враховуючи, чи говорите ви про CPython, IronPython або PyPy. Особливо це стосується мов, які використовують VM, оскільки швидкість буде безпосередньо впливати на якість VM.

Як осторонь, я працюю із системою, яка з різних причин не може використовувати JIT на нашому пристрої з дуже популярною JavaScript VM, яка зазвичай підтримує його. Це означає, що наш 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.


8
Чому це було знято? Це саме відповідь: продуктивність - це лише справа науково-дослідних та інженерних зусиль, а отже, в кінцевому рахунку, грошей. Компанії, що виробляють реалізацію Java, просто стають багатшими, ніж ті, що виробляють Python або PHP. Це все.
Йорг W Міттаг

1
Крім того, я впевнений, що оптимізації CPython не приймаються, якщо вони роблять код занадто важким для читання і лише дуже мало покращують продуктивність.
cgt

2
+ Йорг W Міттаг: Я не згоден. Деякі мовні особливості можуть бути дуже важко виконати ефективно, тому вони роблять створення ефективної реалізації дуже важким або поруч неможливим. З іншого боку, створити "ефективну" реалізацію мови "Асемблер" надзвичайно просто.
користувач281377

@ammoQ Я підозрюю, що багато чого зводиться до типів систем і, зокрема, до можливості точно знати, який тип у вас є, і яка точна семантика допустимих операцій. Динамічні мови отримують гнучкість від своєї природи, але ускладнюють виконання доказів типу (і так компілювати для безпечного гіпершвидкого коду).
Стипендіати Дональ

1
@DonalFellows Точно моя думка. Чим менше відомо в час компіляції, тим більше потрібно з'ясувати під час виконання.
користувач281377

4

Чому Java найшвидший:

Статично набраний + компіляція JIT + - сервер для агресивного перекомпілювання запущеного коду.

Чому 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/


Насправді 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, поки коментатор не вказав на наші недоліки у еталоні ... Отже, візьміть це із зерном сіль. :)
Аякс

З цього приводу, вузол і php також однопоточні, і якщо вам не подобається налаштовувати проксі-сервери кластерів (наприклад, haproxy), я б не торкнувся жодного з них у серйозних виробничих умовах.
Аякс

1

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

Не дивно, що Python досить добре справляється зі складною математикою, якщо врахувати, де і чому це було вперше написано .

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.