2014-09-10 16 views
5

Używam kompilatora Google Closure do kompilowania automatycznie javascript za pomocą PHP (jest to potrzebne w ten sposób - w PHP, bez żadnych ograniczeń bezpieczeństwa na komputerze z systemem Windows). Napisałem prosty skrypt PHP, który wywołuje proces, przekazuje zawartość .js do stdin i odbiera skompilowany .js przez stdout. Działa to dobrze, problem polega na tym, że kiedy kompiluję na przykład 40 plików .js, zajmuje ona silną maszynę prawie 2 minuty. Jednak opóźnienie burmistrza jest spowodowane tym, że java uruchamia nowe wystąpienie aplikacji .jar dla każdego skryptu. Czy istnieje sposób modyfikowania poniższego skryptu w celu utworzenia tylko jednego procesu i wysłania/odebrania .js treści wiele razy przed zakończeniem procesu?Wiele akcji stdin/stdout podczas jednego wywołania procesu

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; 
} 

widzę kilka opcji, ale nie wiem czy jest to możliwe i jak to zrobić:

  1. Tworzenie procesu odtworzyć tylko raz i rur dla każdego pliku
  2. Siła Java zachowaj JIT-ed .jar w pamięci dla znacznie szybszego ponownego wykonywania
  3. Jeśli PHP nie może tego zrobić, możliwe jest użycie bridge'a (innego pliku .exe, który za każdym razem uruchamia się szybko, przesyła stdin/out i przekierowuje go do działający kompilator, jeśli coś takiego jeszcze istnieje)

Odpowiedz

5

To naprawdę jest kwestia koordynacji między tymi dwoma procesami.

Tutaj napisałem krótki 10-minutowy skrypt (tylko dla zabawy), który uruchamia JVM i wysyła wartość całkowitą, która Analizuje java i powroty zwiększany .. który PHP po prostu odesłać go 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(); 
    } 
    } 
} 

Aby uruchomić skrypt po prostu umieścić te pliki w tym samym folderze i zrobić

$ php PHP.php 

należy rozpocząć widząc numery drukowane jak:

1 
2 
3 
. 
. 
. 

pamiętać, że te liczby są drukowane przez PHP, oni są generowane przez Javę

0

Nie sądzę, że # 1 z twojej listy jest możliwe, ponieważ compiler.jar musiałaby mieć natywne wsparcie dla utrzymania procesu przy życiu, którego nie ma (i jeśli uważasz, że algorytm kompresji potrzebuje en wejście opony zanim rozpocznie się przetwarzanie danych, ma sens, że proces nie pozostaje żywy).

Według Anyway to Boost java JVM Startup Speed? niektórzy ludzie są w stanie zmniejszyć ich czas uruchamiania JVM z nailgun

pistolet na gwoździe to klient, protokół i serwer do uruchamiania programów Java z wiersza polecenia bez powodowania narzutu uruchamiania JVM . Programy działają na serwerze (zaimplementowanym w Javie) i są wyzwalane przez klienta (napisane w C), który obsługuje wszystkie operacje we/wy.

Powiązane problemy