5

プログラムを数回実行して、STDERR と STDOUT の両方に約 350 行の出力を生成するスクリプトがあります。ここで、Java でスクリプトを実行する必要があります。これにより、出力ストリームが元の宛先に出力されます。したがって、基本的には、ユーザーの元の動作を維持しながら、Java クラス内からスクリプトを実行します。

私がこれを行う方法は、Java Runtime.exec からストリームを読み取るなどの提案から着想を得ており、機能的には正常に動作します。

Process p = Runtime.getRuntime().exec(cmdarray);
new Thread(new ProcessInputStreamHandler(p.getInputStream(), System.out)).start();
new Thread(new ProcessInputStreamHandler(p.getErrorStream(), System.err)).start();
return p.waitFor();

そしてクラスProcessInputStreamHandler

class ProcessInputStreamHandler implements Runnable {
    private BufferedReader in_reader;
    private PrintStream out_stream;

    public ProcessInputStreamHandler(final InputStream in_stream, final PrintStream out_stream) {
        this.in_reader  = new BufferedReader(new InputStreamReader(in_stream));
        this.out_stream = out_stream;
    }

    @Override public void run() {
        String line;
        try {
            while ((line = in_reader.readLine()) != null) {
                out_stream.println(line);
            }
        } catch (Exception e) {throw new Error(e);}

        out_stream.flush();
    }
}

今、私の問題文について: スクリプトの実行には約 17 秒かかりますが、「カプセル化された」実行には少なくとも 21 秒かかります。この 4 秒以上はどこで失われますか?

私はすでに、 https://github.com/axiak/java_posix_spawnのようなライブラリで POSIX vfork を使用し、a の代わりにバイト バッファを使用してProcessBuilder、STDERR から STDOUT へのリダイレクトで a を使用しようとしましたが、肯定的な結果はまったくありませんでした。BufferedReader

何か提案はありますか?パフォーマンスが多少低下することは理解していますが、4秒は私には少し長すぎるようです...

提案をお待ちしております。

よろしくお願いいたします。

4

2 に答える 2

5

タスクの最速の方法は、Java 7 を使用することです。

return new ProcessBuilder(cmdarray).inheritIO().start().waitFor();

それが役に立たない場合、他のすべてのアプローチでは、処理する必要のあるランタイム環境にさらに多くのコードが追加されるため、できることは何もないと思います。

于 2013-10-29T12:24:56.547 に答える
1

パフォーマンスが向上するかどうかはわかりませんが、非ブロッキング (非同期) I/O を提供しながら Linux で vfork を使用するNuProcessライブラリを試すことができます。これにより、プロセスの起動時間 (およびメモリ オーバーヘッド) が減少します。かなり。

于 2013-11-20T03:34:23.660 に答える