2014-09-10 5 views
5

Ich benutze den Google Closure Compiler, um automatisch Javascript mit PHP zu kompilieren (wird benötigt, um es so zu machen - in PHP, ohne Sicherheitseinschränkungen auf Windows-Rechner). Ich schrieb einfaches PHP-Skript, das Prozess aufruft, .js-Inhalt an stdin übergibt und neu kompilierte .js über stdout empfängt. Es funktioniert gut, Problem ist, wenn ich zum Beispiel 40 .js Dateien kompiliere, dauert es starke Maschine fast 2 Minuten. Die größte Verzögerung liegt jedoch darin, dass Java für jedes Skript eine neue Instanz der .jar-App startet. Gibt es eine Möglichkeit, das Skript unten zu ändern, um nur einen Prozess zu erstellen und den .js-Inhalt mehrmals zu senden/empfangen, bevor der Prozess endet?Mehrere stdin/stdout-Aktionen während eines Prozessaufrufs

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

ich mehrere Optionen sehen kann, aber nicht wissen, ob es möglich ist und wie es zu tun:

  1. Prozess einmal erstellen und erstellen Sie nur Rohre für jede Datei
  2. Force-java halte JIT-ed .jar im Speicher für eine viel schnellere Re-Ausführung
  3. Wenn PHP es nicht kann, ist es möglich, Bridge (eine andere .exe-Datei, die jedes Mal schnell starten, übertragen stdin/out und leitet es um laufender Compiler; wenn so etwas überhaupt existiert)

Antwort

5

Dies ist wirklich eine Frage der Koordination zwischen den beiden Prozessen.

Hier schrieb ich eine schnelle Skript 10 Minuten (nur für den Spaß), die eine JVM startet und sendet einen Integer-Wert, der Java-Parsen und .. erhöht kehrt die PHP wird es nurad-infinitum zurückschicken.

.

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

das Skript einfach gesagt, diese Dateien im gleichen Ordner auszuführen und

$ php PHP.php 

Sie sollten wie die Zahlen zu sehen, die gedruckt beginnen zu tun:

1 
2 
3 
. 
. 
. 

Beachten Sie, dass, während diese Zahlen werden von PHP gedruckt, sie werden tatsächlich von Java generiert

0

Ich glaube nicht, # 1 aus Ihrer Liste ist möglich, weil compiler.jar würde native Unterstützung für den Prozess am Leben zu halten, was es nicht (und wenn Sie, dass ein Komprimierungsalgorithmus benötigt die en Reifen-Eingabe, bevor es mit der Verarbeitung von Daten beginnen kann, macht es Sinn, dass der Prozess nicht am Leben bleibt).

Nach Anyway to Boost java JVM Startup Speed? einige Leute in der Lage gewesen, ihre Jvm Startzeiten zu reduzieren, die mit nailgun

Nailgun ist ein Client, Protokoll und Server für von der Kommandozeile Java-Programme laufen, ohne den JVM-Startoverhead zu verursachen . Programme laufen auf dem Server (der in Java implementiert ist) und werden ausgelöst vom Client (geschrieben in C), der alle I/O behandelt.

Verwandte Themen