Perché Python è più lento di Java ma più veloce di PHP [chiuso]


17

Ho visto molte volte vari parametri di riferimento che mostrano come un gruppo di lingue si esibisce in un determinato compito.

Questi benchmark rivelano sempre che Python è più lento di Java e più veloce di PHP, e mi chiedo perché sia ​​così.

  • Java, Python e PHP vengono eseguiti all'interno di una macchina virtuale
  • Tutte e tre le lingue convertono i loro programmi nei loro codici byte personalizzati che vengono eseguiti sul sistema operativo, quindi nessuno funziona in modo nativo
  • Sia Java che Python possono essere "compilati" ( .pycper Python) ma il __main__modulo per Python non è compilato

Python e PHP sono digitati in modo dinamico e Java staticamente: è questo il motivo per cui Java è più veloce e, in tal caso, spiega come ciò influisce sulla velocità.

E, anche se l'argomento dinamico-vs-statico è corretto, questo non spiega perché PHP sia più lento di Python, perché entrambi sono linguaggi dinamici.

Puoi vedere alcuni benchmark qui e qui e qui


Per quanto riguarda Python vs. PHP: è solo una questione di qualità dell'implementazione, molto probabilmente.
Charles Salvia,

8
@good_computer La maggior parte dei benchmark sono fatti molto male. C'è stato un altro recente (non credo che tu abbia collegato) che la maggior parte delle persone che lo hanno recensito si sono lamentate del fatto che la lingua che affermava di essere "più veloce" avesse semplicemente il miglior codice ottimizzato. Questo di solito viene fatto inconsciamente da qualcuno che non ha familiarità con le lingue che finiscono per essere considerate "lente", quindi non si rendono conto di scrivere codice migliore in quelle che hanno trovato "veloci".
Izkata,

@good_computer Mi sembra che tu stia rivendicando qualcosa, poiché la tua domanda include il testo " Sempre questi parametri di riferimento rivelano che Python è più lento di Java e più veloce di PHP " e " PHP è più lento di Python ". Rimuovere quelle citazioni e riformulare la domanda come lingua agnostica potrebbe riaprirla.
Briddums,

Questa domanda è davvero sbilanciata : (1) riferimento ai parametri di riferimento non autorevoli condotti su codice molto ingenuamente non ottimizzato scritto da programmatori alle prime armi in lingue che non lo fanno master (come sezionati nei rispettivi fili di commento) e (2) costruito su idee sbagliate sui linguaggi interpretati / bytecode (php / python sono interpretati, i file jtec di bytecoded, python cache sono alberi di sintassi astratti, non bytecode) e lo stato dei tre linguaggi (ci sono versioni compilate sia di python che di php - i python sono più maturi, compilati php, tuttavia, esegue facebook)
ZJR

Risposte:


26

Il codice JVM può essere compilato in modo efficiente JIT, usando un compilatore ad hoc banale (e veloce). Ma lo stesso sarebbe eccezionalmente difficile per PHP e Python, a causa della loro natura tipizzata in modo dinamico. JVM si traduce in un codice nativo piuttosto basso e semplice, abbastanza simile a quello che produrrebbe un compilatore C ++, ma per i linguaggi dinamici dovresti generare un dispaccio dinamico per letteralmente tutte le operazioni di base e per tutte le chiamate al metodo. Questo invio dinamico rappresenta il principale collo di bottiglia per tutte le lingue di questo tipo.

In alcuni casi è possibile eliminare l'invio dinamico (così come le chiamate virtuali in Java) utilizzando un compilatore JIT di traccia molto più complicato. Questo approccio è ancora agli inizi, non sta interpretando in modo troppo astratto, e un simile compilatore probabilmente si strozzerà con le evalchiamate (che sono molto tipiche per i linguaggi dinamici).

Per quanto riguarda la differenza tra Python e PHP, quest'ultima è solo di qualità molto inferiore. Poteva correre più veloce in teoria, ma non lo farà mai.


1
Perché JIT è "eccezionalmente" difficile per i linguaggi dinamici? Guarda v8 o TraceMonkey nel mondo JavaScript: lì JIT funziona perfettamente.
treecoder,

6
@good_computer, le JIT di tracciamento sono notevolmente più complesse delle normali JIT ad hoc e continuano a funzionare molto più lentamente delle JIT per le lingue tipizzate staticamente. Una corretta traccia JIT implicherebbe un'interpretazione astratta completa e si soffocerebbe ad ogni evalchiamata.
SK-logic,

2
Probabilmente ci sono circa un centinaio di ingegneri all'interno del team di compilatori HotSpot di Oracle che non sarebbero d'accordo sulla parte "banale" :-)
Jörg W Mittag,

1
@ JörgWMittag, ovviamente, HotSpot non è così semplice, fa un po 'di analisi statica, sta usando i risultati della profilazione del runtime, ma è ancora molto più semplice di un JIT di traccia corretto. E, direi, HotSpot è troppo complicato e la sua implementazione è, per dirla cortesemente, un po 'troppo dettagliata.
SK-logic,

1
@Frank Shearar, un JIT ad hoc per un linguaggio dinamico è banale come per un linguaggio tipicamente statico (vedi ad esempio LuaJIT). OTOH, un JIT efficiente è una cosa totalmente diversa.
SK-logic

21

C'è un problema generale con questa domanda in quanto è troppo assoluto. Non ha davvero senso dire "la lingua X è più veloce della lingua Y". Un linguaggio informatico in sé non è "veloce" o "lento" perché è semplicemente un modo di esprimere un algoritmo. La vera domanda dovrebbe essere qualcosa nell'ordine di "perché l'implementazione X1 della lingua X è più veloce dell'implementazione Y1 della lingua Y per questo particolare dominio problematico?"

Alcune differenze di velocità cadranno sicuramente dalla lingua stessa poiché alcune lingue sono più facili da implementare in determinati domini rispetto ad altre. Ma molto di ciò che rende veloce un'implementazione non è la lingua. Ad esempio, non puoi davvero dire "Python è più lento di Java" senza considerare se stai parlando di CPython, IronPython o PyPy. Ciò è particolarmente vero per le lingue che utilizzano una macchina virtuale poiché la velocità sarà direttamente influenzata dalla qualità della macchina virtuale.

A parte questo, lavoro con un sistema che per vari motivi non può usare JIT sul nostro dispositivo con una VM JavaScript molto popolare che normalmente lo supporta. Ciò significa che il nostro JavaScript funziona molto, molto più lentamente rispetto a un PC con un processore simile. Quella modifica, che non è direttamente correlata al linguaggio stesso, porta JavaScript da "alcune volte più lento del C ++" a "ordini di grandezza più lenti del C ++" per i compiti che ci interessano.

Si consideri inoltre che le lingue differiscono per caratteristiche prestazionali in modi che non sono direttamente comparabili. Troppi benchmark traducono semplicemente un programma dalla lingua A alla lingua B e non tengono conto del fatto che le lingue differiscono in quali funzioni sono veloci. (Puoi vederlo in qualsiasi confronto comparativo ragionevole come quelli a cui ti colleghi in quanto spesso hanno note come "grazie a così e così per avermi mostrato come implementarlo nel linguaggio Foo.)

Ad esempio, prendi questo codice Java:

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

Sarebbe tentato di "riscrivere" questo in C ++ e confrontare i tempi di esecuzione:

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

Il fatto è che qualsiasi programmatore C ++ competente vedrà immediatamente che in C ++ questo non è il modo più veloce per fare qualcosa. Puoi velocizzare facilmente le cose cambiandole per renderle più appropriate al C ++:

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

Il punto non è che il C ++ può essere veloce ma piuttosto che scrivere benchmark per confrontare le lingue è davvero, davvero difficile. Per farlo in modo appropriato, devi essere un esperto in entrambe le lingue e scrivere da zero in entrambe le lingue. Anche allora, puoi facilmente imbatterti in aree in cui una lingua eccelle in una determinata attività. Ad esempio, posso scrivere una versione di Towers of Hanoi in C ++ che funzionerà più velocemente di Java su qualsiasi compilatore ragionevole. Posso farlo essenzialmente barando, usando modelli C ++, valutati in fase di compilazione (http://forums.devshed.com/c-programming-42/c-towers-of-hanoi-using-templates-424148.html)

Il punto non è che potrei dire che "C ++ è più veloce di Java" perché il mio programma è tornato all'istante mentre la versione Java funzionava per minuti (e sperando che nessuno notasse che il mio programma ha impiegato mezz'ora per essere costruito). Il punto è che per questo varia caso stretto, C ++ è più veloce. Per altri casi ristretti potrebbe essere il contrario. Quindi non è "C ++ è più veloce", è "C ++ è più veloce nei casi in cui è possibile valutare l'espressione in fase di compilazione utilizzando i modelli". Meno soddisfacente, ma vero.

Le differenze di velocità nelle lingue riguardano principalmente l'implementazione. Le lingue compilate saranno più veloci delle lingue interpretate. La compilazione in codice nativo sarà più veloce della compilazione in codice byte. Ciò avrà molto più effetto di domande come se la lingua sia tipizzata staticamente o meno. E, naturalmente, le buone implementazioni saranno più veloci di quelle cattive.

E non dimenticare che i buoni programmatori produrranno un codice più veloce rispetto ai cattivi programmatori, spesso in una misura che supera abbastanza le differenze linguistiche.


6

Ha a che fare con la qualità del compilatore, il compilatore java è stato continuamente ottimizzato per molto più tempo e l'ottimizzazione è più importante perché tutto il codice è compilato per Java. Non sono sicuro del motivo esatto per cui Python sia più veloce di PHP, ma scommetterei che è dovuto all'influenza di Google con Python.


8
Perché questo è stato downvoted? Questa è esattamente la risposta: le prestazioni sono puramente una questione di ricerca e impegno ingegneristico, e quindi in definitiva denaro. Le aziende che producono implementazioni Java sono solo più ricche di quelle che producono implementazioni Python o PHP. È tutto.
Jörg W Mittag,

1
Inoltre, sono abbastanza sicuro che le ottimizzazioni di CPython non vengano accettate se rendono il codice troppo difficile da leggere e migliorano le prestazioni solo di poco.
cgt

2
+ Jörg W Mittag: non sono d'accordo. Alcune funzionalità linguistiche possono essere molto difficili da implementare in modo performante, quindi rendono molto difficile la creazione di un'implementazione efficiente o quasi impossibile. D'altra parte, è banalmente facile creare un'implementazione "efficiente" del linguaggio "Assembler".
user281377

@ammoQ Sospetto che gran parte di ciò dipenda dai sistemi di tipo e in particolare dalla capacità di sapere esattamente quale tipo hai e quali sono le esatte semantiche delle operazioni consentite. I linguaggi dinamici ottengono flessibilità dalla loro natura, ma rendono più difficile eseguire le prove di tipo (e quindi compilare un codice iperveloce sicuro).
Donal Fellows

1
@DonalFellows Esattamente il mio pensiero. Meno è noto al momento della compilazione, più deve essere capito durante il runtime.
user281377,

4

Perché Java è il più veloce:

Digitato staticamente + JIT compile + --server flag per ricompilare in modo aggressivo il codice in esecuzione.

Perché Python è più veloce di PHP:

Python potrebbe essere un linguaggio dinamico, ma è ancora fortemente tipizzato. Ciò significa che le strutture codificate sono in grado di ottimizzare il runtime.

Perché PHP fa schifo:

Fondamentalmente è javascript sul server (nessun supporto multithreading, totalmente dinamico, liberamente scritto).

In sostanza, più il compilatore conosce il tuo codice, più può ottimizzare. Java è completamente ottimizzabile prima di essere eseguito e mentre è in esecuzione. Python è ottimizzabile mentre è in esecuzione e PHP è, beh, terribile. Facebook in effetti traspila il loro PHP in C prima che arrivi sul server.
https://developers.facebook.com/blog/post/2010/02/02/hiphop-for-php--move-fast/


In realtà javascript sul server è Node.JS e da quello che capisco (anche se non lo confermerò) il motore V8 supera PHP in generale (anche se probabilmente non di una tonnellata). Inoltre dovresti menzionare che Python può essere compilato in nativo (come funziona rispetto a Java allora?)
Jimmy Hoffa

Non ho usato python abbastanza ampiamente per aiutarti, ma posso dire che nodejs che esegue V8 ha il supporto per le estensioni C native (sebbene attraversare il confine JS / C sia presumibilmente lento), inoltre può sfruttare il compilatore JIT di Google. .. Non sarei sorpreso se il nodo è più veloce sia di Python che di PHP. Ecco un benchmark (imperfetto come molti altri) blog.famzah.net/2010/07/01/… Nota che il java sembrava più lento di JS fino a quando un commentatore ha indicato i nostri difetti nel benchmark ... Quindi, prendilo con un grano di sale. :)
Ajax,

Detto questo, node e php sono anche entrambi singlethreaded e, a meno che non ti piaccia impostare proxy di cluster (come haproxy), non toccherei nessuno dei due in un serio ambiente di produzione.
Ajax,

1

I parametri di riferimento sono piuttosto distorti a favore di una pesante programmazione matematica.

Non sorprende che Python sia abbastanza bravo in matematica complessa se si considera dove e perché è stato scritto per la prima volta .

PHP d'altra parte è stato scritto per servire pagine Web, può fare altre cose, ma le pagine Web sono ciò che è meglio e è alla pari o migliore di Java in questo compito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.