2014-09-10 24 views
5

Io uso Google Closure Compiler per compilare automaticamente javascript utilizzando PHP (è necessario farlo in questo modo - in PHP, hovewer non ci sono limiti di sicurezza sulla macchina Windows). Ho scritto un semplice script PHP che chiama process, passa il contenuto .js allo stdin e riceve ricompilati .js tramite stdout. Funziona benissimo, il problema è che, quando compilo per esempio, i file .js 40, prende la macchina forte quasi 2 minuti. Tuttavia, il ritardo di Mayor è dovuto al fatto che java avvia una nuova istanza dell'app .jar per ogni script. C'è un modo come modificare lo script qui sotto per creare un solo processo e inviare/ricevere il contenuto .js più volte prima che il processo termini?Più azioni stdin/stdout durante una chiamata di processo

function compileJScript($s) { 
    $process = proc_open('java.exe -jar compiler.jar', array(
     0 => array("pipe", "r"), 1 => array("pipe", "w")), $pipes); 
    if (is_resource($process)) { 
     fwrite($pipes[0], $s); 
     fclose($pipes[0]); 
     $output = stream_get_contents($pipes[1]); 
     fclose($pipes[1]); 
     if (proc_close($process) == 0) // If fails, keep $s intact 
      $s = $output; 
    } 
    return $s; 
} 

posso vedere diverse opzioni, ma non so se è possibile e come farlo:

  1. Creare processo una volta e ricreare solo tubi per ogni file
  2. Forza java mantenere JIT-ed .jar in memoria per una più rapida ripetizione di esecuzione
  3. Se PHP non può farlo, è possibile utilizzare bridge (un altro file .exe che si avvierà velocemente ogni volta, trasferirà stdin/out e lo reindirizzerà a compilatore in esecuzione, se esiste qualcosa del genere anche

risposta

5

Questa è veramente una questione di coordinamento tra i due processi.

Qui ho scritto un breve script di 10 minuti (solo per il divertimento) che lancia una JVM e invia un valore intero, che analizza Java e rendimenti incrementati .. che PHP sarà solo rinviarlo ad-infinitum. .

PHP.php

<?php 

echo 'Compiling..', PHP_EOL; 
system('javac Java.java'); 

echo 'Starting JVM..', PHP_EOL; 
$pipes = null; 
$process = proc_open('java Java', [0 => ['pipe', 'r'], 
            1 => ['pipe', 'w']], $pipes); 

if (!is_resource($process)) { 
    exit('ERR: Cannot create java process'); 
} 

list($javaIn, $javaOut) = $pipes; 

$i = 1; 

while (true) { 

    fwrite($javaIn, $i); // <-- send the number 
    fwrite($javaIn, PHP_EOL); 
    fflush($javaIn); 

    $reply = fgetss($javaOut); // <-- blocking read 
    $i = intval($reply); 

    echo $i, PHP_EOL; 
    sleep(1); // <-- wait 1 second 
} 

Java.java

import java.util.Scanner; 

class Java { 

    public static void main(String[] args) { 

    Scanner s = new Scanner(System.in); 

    while (s.hasNextInt()) { // <-- blocking read 
     int i = s.nextInt(); 
     System.out.print(i + 1); // <-- send it back 
     System.out.print('\n'); 
     System.out.flush(); 
    } 
    } 
} 

Per eseguire lo script semplicemente mettere i file nella stessa cartella e fare

$ php PHP.php 

si dovrebbe iniziare a vedere i numeri in fase di stampa come:

1 
2 
3 
. 
. 
. 

Nota che mentre quei numeri sono stampati da PHP, hanno sono in realtà generati da Java

0

Non penso che il numero 1 dal tuo elenco sia possibile perché compiler.jar dovrebbe avere il supporto nativo per mantenere il processo attivo, cosa che non funziona (e se si considera che un algoritmo di compressione necessita l'en input pneumatici prima che possa iniziare l'elaborazione dei dati, ha senso che il processo non rimanga attivo).

Secondo Anyway to Boost java JVM Startup Speed? alcune persone sono stati in grado di ridurre i tempi di avvio di JVM con nailgun

Nailgun è un client, protocollo, e il server per l'esecuzione di programmi Java dalla riga di comando senza incorrere l'avvio in testa JVM . I programmi vengono eseguiti nel server (implementato in Java) e sono attivati ​​dal client (scritto in C), che gestisce tutto l'I/O.