php proc открывает медленную передачу входных данных в java


Я использую proc_open в php для вызова 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");

}

Я передаю в java html-файл 3800 строк (размером ~200 КБ в качестве отдельного файла). Это разбитое время выполнения в журнале файл:

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

Мой вопрос таков: почему ввод занимает в 100 раз больше времени, чем вывод? Есть ли способ сделать это быстрее?

Author: Caballero, 2013-08-06

1 answers

Проверьте свой блок чтения в программе Java: Попробуйте использовать StringBuilder для объединения данных (вместо использования += на 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: Попробуйте загрузить программу Java из оболочки, просто используйте cat для передачи данных (в системе UNIX, такой как Linux). В качестве альтернативы, перепишите свою программу Java, чтобы она также принимала параметр командной строки для файла. Затем вы можете судить, достаточно ли быстро ваш PHP-код передает данные.

Что касается программы Java: Если вы проводите анализ производительности, рассмотрите рекомендации в Как мне написать правильный микро-бенчмарк на Java

 0
Author: Beryllium, 2017-05-23 12:14:09