我使用Google Closure Compiler来使用PHP自动编译javascript(需要这样做(在PHP中,Windows计算机上没有安全限制))。我编写了简单的PHP脚本,该脚本调用流程,将.js内容传递到stdin并通过stdout接收重新编译的.js。它工作正常,问题是,当我编译例如40个.js文件时,它占用了将近2分钟的强大计算机。但是,市长的延迟是因为Java为每个脚本启动了.jar应用程序的新实例。有什么方法可以修改下面的脚本以仅创建一个进程并在进程结束之前多次发送/接收.js内容?

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

我可以看到几个选项,但不知道这是否可行以及如何执行:
  • 创建过程一次,仅为每个文件重新创建管道
  • 强制Java将JIT版本的.jar保留在内存中,以便更快地重新执行
  • 如果PHP无法做到,则可以使用bridge(每次将快速启动的另一个.exe文件,将stdin/out传输并将其重定向到正在运行的编译器;如果甚至存在这种情况)

    最佳答案

    这实际上是两个过程之间协调的问题。

    在这里,我编写了一个10分钟的快速脚本(只是为了好玩),该脚本启动JVM并发送一个整数值,该值将由Java解析并返回递增的值。

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

    要运行脚本,只需将这些文件放在同一文件夹中并执行
    $ php PHP.php
    

    您应该开始看到正在打印的数字,例如:
    1
    2
    3
    .
    .
    .
    

    请注意,虽然这些数字是由PHP打印的,但实际上是由Java生成的

  • 10-04 22:37
    查看更多