2

我在 php 中使用 proc_open 来调用 java 应用程序,将要处理的文本传递给它并读取输出文本。Java 执行时间很长,我发现其原因是读取输入花费了大部分时间。我不确定是php还是java的错。

我的PHP代码:

$process_cmd = "java -Dfile.encoding=UTF-8 -jar test.jar";

$env = NULL;

$options = ["bypass_shell" => true];
$cwd = NULL;
$descriptorspec = [
    0 => ["pipe", "r"],     //stdin is a pipe that the child will read from
    1 => ["pipe", "w"],     //stdout is a pipe that the child will write to
    2 => ["file", "java.error", "a"]
];

$process = proc_open($process_cmd, $descriptorspec, $pipes, $cwd, $env, $options);

if (is_resource($process)) {

    //feeding text to java
    fwrite($pipes[0], $input);
    fclose($pipes[0]);

    //reading output text from java
    $output = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    $return_value = proc_close($process);

}

我的java代码:

public static void main(String[] args) throws Exception {

    long start;
    long end;

    start = System.currentTimeMillis();

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String in;
    String input = "";
    br = new BufferedReader(new InputStreamReader(System.in));
    while ((in = br.readLine()) != null) {
        input += in + "\n";
    }

    end = System.currentTimeMillis();
    log("Input: " + Long.toString(end - start) + " ms");


    start = System.currentTimeMillis();

    org.jsoup.nodes.Document doc = Jsoup.parse(input);

    end = System.currentTimeMillis();
    log("Parser: " + Long.toString(end - start) + " ms");


    start = System.currentTimeMillis();

    System.out.print(doc);

    end = System.currentTimeMillis();
    log("Output: " + Long.toString(end - start) + " ms");

}

我正在传递 3800 行的 java html 文件(作为独立文件的大小约为 200KB)。这些是日志文件中细分的执行时间:

Input: 1169 ms
Parser: 98 ms
Output: 12 ms

我的问题是:为什么输入比输出长 100 倍?有没有办法让它更快?

4

1 回答 1

0

检查 Java 程序中的读取块:尝试使用 aStringBuilder连接数据(而不是使用+=on a String):

String in;
StringBuilder input = new StringBulider();
br = new BufferedReader(new InputStreamReader(System.in));
while ((in = br.readLine()) != null) {
    input.append(in + "\n");
}

此处介绍了详细信息:为什么明确使用 StringBuilder


一般来说,为了让它更快,考虑使用一个应用服务器(或者一个简单的基于套接字的服务器),来拥有一个永久运行的 JVM。启动 JVM 时总会有一些开销,除此之外,JIT 还需要一些时间来优化代码。在 JVM 退出后,这种努力就会丢失。

至于 PHP 程序:尝试从 shell 中输入 Java 程序,只使用cat管道传输数据(在 Linux 等 UNIX 系统上)。作为替代方案,重写您的 Java 程序以也接受文件的命令行参数。然后您可以判断您的 PHP 代码是否足够快地传输数据。

至于 Java 程序:如果您进行性能分析,请考虑如何在 Java 中编写正确的微基准测试中的建议

于 2013-08-06T09:05:08.437 回答