2012-05-23 8 views
36

Desde mi punto de vista, tanto PHP como Java tienen una estructura similar. Al principio, escribe un código de alto nivel, que luego debe traducirse en un formato de código más simple para que lo ejecute una máquina virtual. Una diferencia es que PHP trabaja directamente desde los archivos de código fuente, mientras que Java almacena el bytecode en archivos .class, desde donde la VM puede cargarlos.¿Por qué PHP usa cachés de códigos de operación mientras que Java los compila a archivos de códigos de bytes?

En la actualidad crecen los requisitos para una ejecución rápida de PHP, lo que lleva a las personas a pensar que sería mejor trabajar directamente con los códigos de operación y no realizar el paso de compilación cada vez que un usuario acceda a un archivo.

La solución parece ser a load of so called Accelerators, que básicamente almacena los resultados compilados en caché y luego utiliza los códigos de operación en caché en lugar de compilar de nuevo.

Otro enfoque, hecho por Facebook, es el código completely compile the PHP a un idioma diferente.

Así que mi pregunta es, ¿por qué nadie en el mundo de PHP hace lo que hace Java? ¿Hay algunos elementos dinámicos que realmente necesitan ser recompilados cada vez o algo así? De lo contrario, sería más inteligente compilar todo cuando el código entre en producción y luego simplemente trabaje con eso.

+5

Columpios y rotondas. Uno produce tiempos de ejecución más rápidos, el otro puede implementarse rápidamente. – GordonM

Respuesta

52

La diferencia más importante es que la JVM tiene una especificación explícita que cubre completamente el bytecode. Esto hace que los archivos de bytecode sean portátiles y útiles para algo más que la ejecución mediante una implementación de JVM específica.

PHP ni siquiera tiene una especificación de lenguaje . Los códigos de operación de PHP son un detalle de implementación de un motor PHP específico, por lo que no puedes hacer nada realmente interesante con ellos y no tiene sentido hacerlos más visibles.

+0

Pero, ¿mi sistema Ubuntu LAMP produciría un código de operación diferente al suyo o desde una caja de Windows? – erikbwork

+0

@erikb - poco probable, pero podría ser, el motor Zend (aunque con diferencia el más popular) no es la única opción, y también hay opciones como Caucho Resin o IBM Project Zero para convertir sus scripts PHP en bytecode de Java en lugar de Bytecodes PHP –

+0

@erikb: no hay nada que diga que tienen que producir los mismos códigos de operación. Probablemente sí si ambos ejecutan la misma versión del motor Zend, pero incluso sin tener en cuenta las implementaciones alternativas, tan pronto como difieran las versiones, no me gustaría depender de ello. –

4

No es cierto que nadie en el mundo de PHP está haciendo lo que hace java. Proyectos como Alexey Zakhlestin's appserver proporcionan un grado de persistencia más parecido a un contenedor de servlets java (aunque su inspiración es más de Ruby's Rack y WSGI de Python que Java)

12

Los códigos de operación de PHP no son los mismos que los de clase de Java. Los archivos de clase Java están bien especificados y son portátiles entre las máquinas. Los códigos de operación de PHP no son portátiles de ninguna manera. Tienen direcciones de memoria horneadas en ellos, por ejemplo. Son estrictamente un detalle de implementación del intérprete de PHP, y no deben considerarse como bytecode de Java.

¿Tiene que ser así? No, probablemente no. Pero el código fuente de PHP es un desastre, y no existe el deseo, ni la voluntad política en la comunidad interna de PHP para que esto suceda. Creo que se habló de preparar un caché de código de operación en PHP 6, pero PHP 6 murió, y no sé el estado de esa idea.

Referencia: Escribí phc así que estaba bastante hundido hasta las rodillas en PHP aplicación/compilación durante algunos años.

+0

PHP tiene un caché de código de operación incluido desde 5.5 – Andrea

3

PHP no utiliza un mecanismo estándar para los códigos de operación. Ojalá esté pegado a una pila VM (python, java) o una máquina virtual de registro (x86, perl6, etc.). Pero utiliza algo absolutamente local y allí radica el problema.

Utiliza una lista conectada en memoria que hace que cada código de operación tenga un resultado -> op1 -> op2 y ->. Ahora cada uno de ellos son constantes o entradas en una tabla temporal, etc. Estos punteros no se pueden serializar de ninguna manera.

Ahora, la gente ha logrado esto utilizando elementos como pecl/bcompiler que hace volcar la secuencia en el disco.

Pero las clases, esto es aún más complicado, lo que significa que hay fragmentos de código potenciales como

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

class ABC extends XYZ {} 

Lo que significa que un gran número de decisiones acerca de las clases & funciones sólo puede hacerse en tiempo de ejecución - algo así como Java se ahogaría en dos clases con el mismo nombre, que se definen condicionalmente en tiempo de ejecución. Básicamente, el código de caché de clase & de herencia de APC es quizás la parte más complicada de la base de código &. Cada vez que se almacena en caché una clase, todos los miembros heredados deben eliminarse antes de que se pueda guardar en el caché del código de operación.

El problema del puntero no es insuperable. Hay un apc_bindump que nunca me he molestado en arreglar para cargar entradas de caché completas del disco directamente cada vez que se realiza un reinicio. Pero es doloroso depurar todo eso para obtener algo que todavía necesita localizar todos los punteros del sistema: el caso de apache es demasiado fácil, porque todos los procesos php tienen los mismos punteros del sistema debido al comportamiento de la horquilla. Las viejas versiones de fastcgi eran más lentas porque solían bifurcar primero & init php más tarde - el php-fpm solucionó eso haciéndolo al revés.

Pero finalmente, lo que realmente falta en PHP es la voluntad de inventar un formato de bytecode, descartar el motor actual & todos los módulos - para reescribirlo utilizando una pila VM & crear un JIT. Ojalá tuviera tiempo, los chicos de FB casi están allí con su HHVM de hiphop. ¿Qué sacrifica eval() para un rendimiento más rápido - que es un sacrificio justo :)

PS: Soy el tipo que no puede encontrar el tiempo para actualizar el 5,4 APC adecuadamente

3

Creo que todos ustedes están mal informados . HHVM no es un compilador de otro languague es una máquina virtual en sí misma. La confusión se debe a que Facebook utiliza para compilar a C++, pero ese enfoque fue lento para los requisitos de los desarrolladores (diez minutos compilando solo para probar algunas cosas pequeñas).

+1

Por favor, publique este tipo de información adicional sobre otra respuesta como comentario a esa respuesta. Si publica dicha información como respuesta, se rechazará en algún momento porque no responde la pregunta. – erikbwork

Cuestiones relacionadas