2012-05-23 6 views
36

Dal mio punto di vista, sia PHP che Java hanno una struttura simile. All'inizio scrivi del codice di alto livello, che poi deve essere tradotto in un formato di codice più semplice per essere eseguito da una VM. Una differenza è che PHP lavora direttamente dai file del codice sorgente, mentre Java memorizza il bytecode in file .class, da cui la VM può caricarli.Perché PHP utilizza le cache opcode mentre Java compila i file bytecode?

Al giorno d'oggi crescono i requisiti per l'esecuzione rapida di PHP, che inducono le persone a credere che sarebbe meglio lavorare direttamente con gli opcode e non passare attraverso la fase di compilazione ogni volta che un utente raggiunge un file.

La soluzione sembra essere a load of so called Accelerators, che fondamentalmente memorizzare i risultati compilati nella cache e quindi utilizzare i codici operativi memorizzati nella cache invece di compilare di nuovo.

Un altro approccio, fatto da Facebook, è il codice completely compile the PHP in un'altra lingua.

Quindi la mia domanda è: perché nessuno nel mondo PHP fa ciò che fa Java? Ci sono elementi dinamici che devono essere ricompilati ogni volta o qualcosa del genere? Altrimenti sarebbe davvero più intelligente compilare tutto quando il codice andrà in produzione e poi lavorarci sopra.

+5

Altalene e rotatorie. Uno produce runtime più veloci, l'altro può essere implementato rapidamente. – GordonM

risposta

52

La differenza più importante è che la JVM ha una specifica esplicita che copre completamente il bytecode. Ciò rende i file bytecode portatili e utili per qualcosa di più della semplice esecuzione da parte di una specifica implementazione JVM.

PHP non ha nemmeno una specifica di lingua . Gli opcode PHP sono un dettaglio di implementazione di uno specifico motore PHP, quindi non puoi davvero fare nulla di interessante con loro e non ha molto senso renderli più visibili.

+0

Ma il mio sistema Ubuntu LAMP produce un codice operativo diverso dal tuo o da una casella di Windows? – erikbwork

+0

@erikb - improbabile ma potrebbe, il motore Zend (sebbene di gran lunga il più popolare) non è l'unica opzione, e ci sono anche opzioni come Caucho Resin o Project Zero di IBM per convertire i tuoi script PHP in bytecode Java piuttosto che Bytecode PHP –

+0

@erikb: non c'è nulla che dice che devono produrre gli stessi codici opzionali. Probabilmente lo fanno se entrambi eseguono la stessa versione del motore Zend, ma ignorando anche le implementazioni alternative, non appena le versioni saranno diverse, non vorrei dipendere da esso. –

4

Non è vero che nessuno nel mondo PHP sta facendo quello che fa java. Progetti come Alexey Zakhlestin's appserver forniscono un grado di persistenza più simile a un contenitore di servlet java (anche se la sua ispirazione è più Ruby's Rack e Python WSGI che Java)

12

Gli opcode PHP non sono gli stessi dei file di classe Java. I file di classe Java sono ben specificati e sono portatili tra le macchine. Gli opcodes PHP non sono portatili in alcun modo. Ad esempio, hanno indirizzi di memoria infornati. Sono strettamente un dettaglio di implementazione dell'interprete PHP e non dovrebbero essere considerati nulla come il bytecode Java.

Deve essere così? No, probabilmente no. Ma il codice sorgente PHP è un disastro, e non c'è né il desiderio, né la volontà politica nella comunità interna di PHP di farlo accadere. Penso che si sia parlato di cuocere una cache di opcode in PHP 6, ma PHP 6 è morto e non conosco lo stato di questa idea.

Riferimento: Ho scritto phc quindi ero abbastanza al ginocchio nell'implementazione/compilazione di PHP per alcuni anni.

+0

PHP ha una cache di opcode in bundle dal 5.5 – Andrea

3

PHP non utilizza un meccanismo standard per gli opcode. Vorrei che fosse bloccato su una pila VM (python, java) o su un registro VM (x86, perl6 ecc.). Ma usa qualcosa di assolutamente homegrown e là in menzogna lo sfregio.

Utilizza una lista collegata in memoria che risulta in ogni opcode avente un risultato -> op1 -> op2 e ->. Ora ognuno di questi è una costante o una voce in una tabella temporanea, ecc. Questi puntatori non possono essere serializzati in modo sano.

Ora, le persone hanno realizzato questo utilizzando elementi come pecl/bcompiler che esegue il dump dello stream nel disco.

Ma le classi rendono ancora più complicato, il che significa che ci sono potenziali frammenti di codice come

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

class ABC extends XYZ {} 

Il che significa che un gran numero di decisioni circa le classi & funzioni può essere fatto solo in fase di esecuzione - qualcosa di simile Java potrebbe soffocare su due classi con lo stesso nome, che sono definite condizionalmente in fase di esecuzione. Fondamentalmente, l'ereditarietà di APC & codice di memorizzazione nella cache è forse la parte più complicata della base di codice &. Ogni volta che una classe viene memorizzata nella cache, tutti i membri ereditati dai genitori devono essere eliminati prima di poter essere salvati nella cache dell'opcode.

Il problema del puntatore non è insormontabile. C'è un apc_bindump che non mi sono mai preoccupato di sistemare per caricare intere voci della cache dal disco direttamente ogni volta che viene eseguito un riavvio. Ma è difficile eseguire il debug di tutto ciò per ottenere qualcosa che ha ancora bisogno di localizzare tutti i puntatori di sistema - il caso Apache è troppo facile, perché tutti i processi php hanno gli stessi puntatori di sistema a causa del comportamento della forcella. Le vecchie versioni di fastcgi erano più lente perché prima inizializzavano il php & init - il php-fpm lo risolveva facendo il contrario.

Ma alla fine, ciò che è veramente manca in PHP è la volontà di inventare un formato bytecode, buttare via il motore corrente & tutti i moduli - di riscrivere utilizzando una pila VM & costruire una JIT. Vorrei avere il tempo - i ragazzi fb sono quasi arrivati ​​con il loro hiphop HHVM. Quali sacrifies eval() per prestazioni più veloci - che è un sacrificio giusto :)

PS: io sono il tipo che non riesce a trovare il tempo per aggiornare APC per 5.4 correttamente

3

Credo che tutti voi sono male informato . HHVM non è un compilatore di un'altra lingua è una macchina virtuale stessa. La confusione è dovuta al fatto che Facebook usa per compilare in C++, ma questo approccio era lento per le esigenze degli sviluppatori (dieci minuti di compilazione solo per testare alcune piccole cose).

+1

Si prega di inviare questo tipo di informazioni aggiuntive su un'altra risposta come commento a quella risposta. Se pubblichi tali informazioni come risposta, a un certo punto verrà rifiutato, perché non risponde alla domanda posta. – erikbwork

Problemi correlati