Pourquoi Python est plus lent que Java mais plus rapide que PHP [fermé]

17

J'ai vu à plusieurs reprises divers repères qui montrent comment un tas de langues fonctionnent sur une tâche donnée.

Ces benchmarks révèlent toujours que Python est plus lent que Java et plus rapide que PHP, et je me demande pourquoi c'est le cas.

  • Java, Python et PHP s'exécutent dans une machine virtuelle
  • Les trois langues convertissent leurs programmes en leurs codes d'octets personnalisés qui s'exécutent sur le système d'exploitation - donc aucun ne s'exécute en mode natif
  • Java et Python peuvent être "compilés" ( .pycpour Python) mais le __main__module pour Python n'est pas compilé

Python et PHP sont typés dynamiquement et Java statiquement - est-ce la raison pour laquelle Java est plus rapide, et si oui, veuillez expliquer comment cela affecte la vitesse.

Et, même si l'argument dynamique-vs-statique est correct, cela n'explique pas pourquoi PHP est plus lent que Python - car les deux sont des langages dynamiques.

Vous pouvez voir quelques repères ici et ici , et ici

treecoder
la source
Concernant Python vs PHP: c'est juste un problème de qualité d'implémentation, très probablement.
Charles Salvia
8
@good_computer La plupart des benchmarks sont très mal faits. Il y en avait un autre récent (je ne pense pas que vous ayez lié) que la plupart des personnes qui l'ont examiné se sont plaints que le langage qu'il prétendait être "le plus rapide" avait simplement le meilleur code optimisé. Cela est généralement fait inconsciemment par quelqu'un qui n'est pas aussi familier avec les langages qui finissent par être considérés comme "lents", de sorte qu'ils ne réalisent pas qu'ils écrivent un meilleur code dans ceux qu'ils ont trouvés "rapides".
Izkata
@good_computer Il me semble que vous réclamez quelque chose, car votre question inclut le texte " Toujours ces benchmarks révèlent que Python est plus lent que Java et plus rapide que PHP " et " PHP est plus lent que Python ". La suppression de ces citations et la reformulation de la question pour qu'elle soit indépendante du langage pourrait la rouvrir.
briddums
Cette question est vraiment biaisée : (1) se référant à des tests de référence sans autorité effectués sur du code très naïvement non optimisé écrit par des programmeurs novices dans des langues qu'ils ne maîtrisent pas (comme disséqué dans les fils de commentaires respectifs) et (2) construit sur des idées fausses sur les langages interprétés / bytecode (php / python sont interprétés, les fichiers de cache python bytecoded de java sont des arbres de syntaxe abstraite, pas bytecode) et l'état des trois langages (il existe des versions compilées de python et php - les python sont plus matures, compilés php, cependant, exécute facebook)
ZJR

Réponses:

26

Le code JVM peut être compilé JIT efficacement, en utilisant un compilateur ad hoc trivial (et rapide). Mais la même chose serait exceptionnellement difficile pour PHP et Python, en raison de leur nature typée dynamiquement. JVM se traduit par un code natif assez bas et simple, assez similaire à ce que produirait un compilateur C ++, mais pour les langages dynamiques, vous auriez à générer une répartition dynamique pour littéralement toutes les opérations de base et pour tous les appels de méthode. Cette répartition dynamique est le principal goulot d'étranglement pour toutes les langues de ce type.

Dans certains cas, il est possible d'éliminer la répartition dynamique (ainsi que les appels virtuels en Java) en utilisant un compilateur JIT de traçage beaucoup plus compliqué. Cette approche est encore à ses balbutiements, ne faisant pas trop d'interprétation abstraite, et un tel compilateur est susceptible d'étouffer les evalappels (qui sont très typiques pour les langages dynamiques).

Quant à la différence entre Python et PHP, ce dernier est juste d'une qualité bien inférieure. Il pourrait fonctionner plus rapidement en théorie, mais il ne le sera jamais.

SK-logic
la source
1
Pourquoi JIT est-il "exceptionnellement" difficile pour les langages dynamiques? Regardez v8 ou TraceMonkey dans le monde JavaScript - là, JIT fonctionne très bien.
treecoder
6
@good_computer, le traçage des JIT est notablement plus complexe que la normale, les JIT ad hoc, et ils fonctionnent toujours beaucoup plus lentement que les JIT pour les langages à typage statique. Une JIT de traçage appropriée impliquerait une interprétation abstraite complète, et elle s'étoufferait à chaque evalappel.
SK-logic
2
Il y a probablement une centaine d'ingénieurs au sein de l'équipe du compilateur HotSpot d'Oracle qui seraient en désaccord sur la partie "triviale" :-)
Jörg W Mittag
1
@ JörgWMittag, bien sûr, HotSpot n'est pas aussi simple, il fait un peu d'analyse statique, il utilise les résultats du profilage d'exécution, mais il est toujours beaucoup plus simple qu'un JIT de traçage approprié. Et, je dirais, HotSpot est trop compliqué et sa mise en œuvre est, pour le dire poliment, un peu trop verbeuse.
SK-logic
1
@Frank Shearar, un JIT ad hoc pour un langage dynamique est aussi trivial que pour un langage typé (voir LuaJIT par exemple). OTOH, un JIT efficace est une chose totalement différente.
SK-logic
21

Il y a un problème général avec cette question en ce qu'elle est trop absolue. Cela n'a pas vraiment de sens de dire "la langue X est plus rapide que la langue Y". Un langage informatique lui-même n'est ni "rapide" ni "lent" car il s'agit simplement d'un moyen d'exprimer un algorithme. La véritable question devrait être de l'ordre de "pourquoi l'implémentation X1 du langage X est-elle plus rapide que l'implémentation Y1 du langage Y pour ce domaine de problème particulier?"

Certaines différences de vitesse vont certainement tomber de la langue elle-même car certaines langues sont plus faciles à implémenter certains domaines que d'autres. Mais une grande partie de ce qui rend une implémentation rapide n'est pas le langage. Par exemple, vous ne pouvez pas vraiment dire "Python est plus lent que Java" sans vous demander si vous parlez de CPython, IronPython ou PyPy. Cela est particulièrement vrai pour les langues qui utilisent une machine virtuelle, car la vitesse sera directement affectée par la qualité de la machine virtuelle.

En passant, je travaille avec un système qui, pour diverses raisons, ne peut pas utiliser JIT sur notre appareil avec une machine virtuelle JavaScript très populaire qui le prend normalement en charge. Cela signifie que notre JavaScript fonctionne beaucoup plus lentement que sur un PC avec un processeur similaire. Cette seule modification, qui n'est pas directement liée au langage lui-même, fait passer JavaScript de «quelques fois plus lent que C ++» à «d'ordre de grandeur plus lent que C ++» pour les tâches qui nous intéressent.

Tenez également compte du fait que les langues diffèrent dans leurs caractéristiques de performance de manière qui ne sont pas directement comparables. Trop de benchmarks traduisent simplement un programme de la langue A vers la langue B et ne tiennent pas compte du fait que les langues diffèrent dans les fonctionnalités qui sont rapides. (Vous pouvez le voir dans n'importe quelle comparaison de référence raisonnable, comme celles auxquelles vous liez, car elles ont souvent des notes comme "merci à tel ou tel pour m'avoir montré comment l'implémenter dans le langage Foo.)

Par exemple, prenez ce code Java:

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

Il serait tentant de "réécrire" cela en C ++ et de comparer les temps d'exécution:

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

Le fait est que tout programmeur C ++ compétent verra immédiatement qu'en C ++, ce n'est pas le moyen le plus rapide de faire quelque chose. Vous pouvez facilement accélérer les choses en le modifiant pour qu'il soit plus approprié au C ++:

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

Le fait n'est pas que le C ++ peut être rapide mais plutôt que d'écrire des benchmarks pour comparer des langages est vraiment, vraiment difficile. Pour le faire correctement, vous devez être un expert dans les deux langues et écrire à partir de zéro dans les deux langues. Même alors, vous pouvez facilement vous heurter à des domaines où une langue excelle dans une tâche particulière. Par exemple, je peux écrire une version de Towers of Hanoi en C ++ qui fonctionnera plus rapidement que Java sur n'importe quel compilateur raisonnable. Je peux le faire en trichant essentiellement, en utilisant des modèles C ++, évalués au moment de la compilation (http://forums.devshed.com/c-programming-42/c-towers-of-hanoi-using-templates-424148.html)

Le point n'est pas que je pourrais dire que "C ++ est plus rapide que Java" parce que mon programme est revenu instantanément alors que la version Java a fonctionné pendant des minutes (et en espérant que personne n'a remarqué que mon programme a pris une demi-heure à construire.) Le fait est que pour cela varier cas étroit, C ++ est plus rapide. Pour d'autres cas étroits, ce pourrait être l'inverse. Ce n'est donc pas «C ++ est plus rapide», c'est «C ++ est plus rapide dans les cas où vous pouvez évaluer l'expression au moment de la construction à l'aide de modèles». Moins satisfaisant, mais vrai.

Les différences de vitesse dans les langues concernent principalement l'implémentation. Les langues compilées seront plus rapides que les langues interprétées. La compilation en code natif sera plus rapide que la compilation en code octet. Cela aura beaucoup plus d'effet que des questions comme si la langue est ou non typée statiquement. Et bien sûr, les bonnes implémentations vont être plus rapides que les mauvaises.

Et n'oubliez pas que les bons programmeurs vont produire du code plus rapidement que les mauvais programmeurs, souvent dans une mesure qui dépasse largement les différences de langue.

Gort le robot
la source
6

Cela a à voir avec la qualité du compilateur, le compilateur de Java a été continuellement optimisé pendant beaucoup plus longtemps, et l'optimisation est plus importante car tout le code est compilé pour Java. Je ne suis pas sûr de la raison exacte pour laquelle python est plus rapide que PHP, mais je parierais son en raison de l'influence de Google avec Python.

Ryathal
la source
8
Pourquoi a-t-on voté C'est exactement la réponse: la performance est purement une question d'efforts de recherche et d'ingénierie, et donc finalement d'argent. Les sociétés qui produisent des implémentations Java sont simplement plus riches que celles qui produisent des implémentations Python ou PHP. C'est tout.
Jörg W Mittag
1
De plus, je suis presque sûr que les optimisations CPython ne sont pas acceptées si elles rendent le code trop difficile à lire et n'améliorent que très peu les performances.
cgt
2
+ Jörg W Mittag: Je ne suis pas d'accord. Certaines fonctionnalités de langage peuvent être très difficiles à implémenter de manière performante, par conséquent, elles rendent la création d'une implémentation efficace très difficile ou presque impossible. D'un autre côté, il est très facile de créer une implémentation "efficace" du langage "Assembleur".
user281377
@ammoQ Je soupçonne que cela dépend en grande partie des systèmes de types et en particulier de la capacité de savoir exactement quel type vous avez et quelle est la sémantique exacte des opérations autorisées. Les langages dynamiques gagnent en flexibilité de par leur nature, mais rendent plus difficile la réalisation de preuves de type (et donc de compilation en code hyper-rapide sûr).
Donal Fellows
1
@DonalFellows Exactement ma pensée. Moins on en sait au moment de la compilation, plus il faut en comprendre pendant l'exécution.
user281377
4

Pourquoi Java est le plus rapide:

Dactylographié de manière statique + Compilation JIT + - Indicateur de serveur pour recompiler agressivement le code en cours d'exécution.

Pourquoi Python est plus rapide que PHP:

Python est peut-être un langage dynamique, mais il est toujours fortement typé. Cela signifie que les structures que vous codez sont capables d'optimisation d'exécution.

Pourquoi PHP craint:

Il s'agit essentiellement de javascript sur le serveur (pas de support multithreading, totalement dynamique, typé de manière lâche).

En substance, plus le compilateur connaît votre code, plus il peut optimiser. Java est entièrement optimisable avant son exécution et pendant son exécution. Python est optimisable pendant son exécution, et PHP est, enfin, terrible. Facebook transpose en fait leur PHP en C avant qu'il n'atteigne le serveur.
https://developers.facebook.com/blog/post/2010/02/02/hiphop-for-php--move-fast/

Ajax
la source
En fait, javascript sur le serveur est Node.JS et d'après ce que je comprends (bien que je ne le prouve pas), le moteur V8 surpasse PHP en général (mais probablement pas d'une tonne). De plus, vous devez mentionner que Python peut être compilé en natif (comment fonctionne-t-il par rapport à Java alors?)
Jimmy Hoffa
Je n'ai pas utilisé python suffisamment pour vous y aider, mais je peux dire que nodejs exécutant V8 prend en charge les extensions C natives (bien que le franchissement de la frontière JS / C soit censé être lent), en plus il peut tirer parti du compilateur JIT de Google. .. Je ne serais pas surpris si le nœud est plus rapide que python et php. Voici un benchmark (imparfait comme la plupart le sont) blog.famzah.net/2010/07/01/… Notez que le java semblait plus lent que JS jusqu'à ce qu'un commentateur pointe nos défauts dans le benchmark ... Alors, prenez-le avec un grain de sel. :)
Ajax
Cela dit, le nœud et le php sont également tous les deux en lecture unique, et à moins que vous n'aimiez configurer des proxys de cluster (comme haproxy), je ne les toucherais pas dans un environnement de production sérieux.
Ajax
1

Les repères sont plutôt biaisés en faveur d'une programmation mathématique lourde.

Il n'est pas surprenant que Python soit assez bon en mathématiques complexes si vous considérez où et pourquoi il a été écrit pour la première fois .

PHP d'autre part a été écrit pour servir des pages Web, il peut faire autre chose, mais les pages Web sont ce qu'il y a de mieux et c'est égal ou meilleur que Java dans cette tâche.

James Anderson
la source