37 votes

Pourquoi PHP utilise-t-il des caches d'opcode alors que Java compile en bytecode ?

De mon point de vue, PHP et Java ont tous deux une structure similaire. Vous écrivez d'abord du code de haut niveau, qui doit ensuite être traduit dans un format de code plus simple pour être exécuté par une machine virtuelle. La différence est que PHP travaille directement à partir des fichiers de code source, alors que Java stocke le bytecode dans des fichiers .class, d'où la VM peut les charger.

De nos jours, les exigences en matière de rapidité d'exécution du PHP augmentent, ce qui amène les gens à penser qu'il serait préférable de travailler directement avec les opcodes et de ne pas passer par l'étape de la compilation à chaque fois qu'un utilisateur frappe un fichier.

La solution semble être un tas de soi-disant accélérateurs qui stockent les résultats de la compilation dans un cache et utilisent ensuite les codes d'opération en cache au lieu de les compiler à nouveau.

Une autre approche, adoptée par Facebook, consiste à compiler complètement le PHP dans une autre langue.

Ma question est donc la suivante : pourquoi personne dans le monde du PHP ne fait ce que fait Java ? Y a-t-il des éléments dynamiques qui ont vraiment besoin d'être recompilés à chaque fois ou quelque chose comme ça ? Sinon, il serait vraiment plus intelligent de tout compiler lorsque le code est mis en production et de travailler ensuite avec cela.

52voto

Michael Borgwardt Points 181658

La différence la plus importante est que la JVM a une spécification explicite qui couvre complètement le bytecode. Cela rend les fichiers de bytecode portables et utiles pour plus que la simple exécution par une implémentation spécifique de la JVM.

PHP n'a même pas de spécification du langage . Les opcodes PHP sont un détail d'implémentation d'un moteur PHP spécifique, donc vous ne pouvez pas vraiment faire quelque chose d'intéressant avec eux et il y a peu d'intérêt à les rendre plus visibles.

12voto

Paul Biggar Points 7108

Les opcodes PHP ne sont pas les mêmes que les fichiers de classe Java. Les fichiers de classe Java sont bien spécifiés, et sont portables entre les machines. Les opcodes PHP ne sont en aucun cas portables. Ils ont des adresses mémoire incorporées, par exemple. Ils sont strictement un détail d'implémentation de l'interpréteur PHP, et ne doivent pas être considérés comme du bytecode Java.

Est-ce que ça doit être comme ça ? Non, probablement pas. Mais le code source de PHP est un désordre, et il n'y a ni le désir, ni la volonté politique dans la communauté interne de PHP pour que cela se produise. Je pense qu'il était question d'intégrer un cache pour les opcodes dans PHP 6, mais PHP 6 est mort, et je ne sais pas où en est cette idée.

Référence : J'ai écrit phc J'ai donc été plongé dans l'implémentation/compilation de PHP pendant quelques années.

4voto

Mark Baker Points 90240

Ce n'est pas tout à fait vrai que personne dans le monde du PHP, c'est faire ce que fait Java. Des projets tels que L'appserver d'Alexey Zakhlestin fournir un degré de persistance plus proche de celui d'un conteneur de servlets Java (bien que son inspiration soit plus proche du Rack de Ruby et du WSGI de Python que de Java).

3voto

t3rmin4t0r Points 31

PHP n'utilise pas de mécanisme standard pour les opcodes. J'aurais aimé qu'il utilise une VM de pile (python, java) ou une VM de registre (x86, perl6 etc). Mais il utilise quelque chose d'absolument artisanal et c'est là que le bât blesse.

Il utilise une liste connectée en mémoire, ce qui fait que chaque opcode a un ->op1 ->op2 et un ->résultat. Chacun de ces éléments est soit une constante, soit une entrée dans une table temporaire, etc. Ces pointeurs ne peuvent pas être sérialisés d'une manière sensée.

Maintenant, les gens ont accompli cela en utilisant des éléments comme pecl/bcompiler qui vide le flux sur le disque.

Mais les classes rendent les choses encore plus compliquées, ce qui signifie qu'il existe des fragments de code potentiels tels que

if(<conditon>)
{
   class XYZ() { }
}
else 
{
   class XYZ() { }
}

class ABC extends XYZ {}

Cela signifie qu'un grand nombre de décisions concernant les classes et les fonctions ne peuvent être prises qu'au moment de l'exécution - quelque chose comme Java s'étoufferait avec deux classes portant le même nom, qui sont définies de manière conditionnelle au moment de l'exécution. En fait, le code d'héritage et de mise en cache des classes d'APC est peut-être la partie la plus compliquée et la plus sujette aux bogues de la base de code. Lorsqu'une classe est mise en cache, tous les membres parentaux hérités doivent être éliminés avant qu'elle puisse être sauvegardée dans le cache opcode.

Le problème des pointeurs n'est pas insurmontable. Il y a un apc_bindump que je n'ai jamais pris la peine de corriger pour charger des entrées de cache entières depuis le disque à chaque fois qu'un redémarrage est effectué. Mais c'est pénible de déboguer tout ça pour obtenir quelque chose qui a encore besoin de localiser tous les pointeurs système - le cas d'apache est trop facile, parce que tous les processus php ont les mêmes pointeurs système à cause du comportement du fork. Les anciennes versions de fastcgi étaient plus lentes parce qu'elles forkaient d'abord et initaient php ensuite - le php-fpm a corrigé cela en faisant l'inverse.

Mais finalement, ce qui manque vraiment à PHP, c'est la volonté d'inventer un format de bytecode, de jeter le moteur actuel et tous les modules - de le réécrire en utilisant une pile VM et de construire un JIT. J'aimerais avoir le temps - les gars de FB y sont presque avec leur HHVM hiphop. Qui sacrifie eval() pour des performances plus rapides - ce qui est un sacrifice juste :)

PS : Je suis le type qui ne trouve pas le temps de mettre à jour APC pour la 5.4 correctement.

3voto

user2187422 Points 31

Je pense que vous êtes tous mal informés. HHVM n'est pas un compilateur vers une autre langue, c'est une machine virtuelle elle-même. La confusion vient du fait que facebook avait l'habitude de compiler en c++, mais cette approche était trop lente pour les exigences des développeurs (dix minutes de compilation seulement pour tester quelques petites choses).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X