简体   繁体   English

加快Java中的外部呼叫

[英]Speed-up external call in Java

I have a program in JAVA that needs to call two other external executables (written in C++) thousands of times per launch. 我有一个JAVA程序,每次启动时需要调用另外两个外部可执行文件(用C ++编写)数千次。 Actual time for calculations in each of them is effectively milliseconds, so the bottleneck of the whole program is calls and write/read to temporary file (external_exe_2 can read its input only from file). 每个计算中的实际时间有效为毫秒,因此整个程序的瓶颈是调用并向临时文件写入/读取(external_exe_2只能从文件读取其输入)。 Also I need to check if there are no errors occurred. 另外,我需要检查是否没有发生错误。

I have a following benchmark test program to measure the performance of external calls: 我有以下基准测试程序来衡量外部呼叫的性能:

long launchtime = (new Date()).getTime();

int n=1000;
String[][] sargs = new String[][]
    {{"external_exe_1", "arg1", "-o", "file.tmp"},
    {"external_exe_2", "arg2", "-i", "file.tmp"}};
String line, message;
Process process;
InputStream stderr;
BufferedReader reader;
StringBuilder bstring;
for (int i=0; i<n; i++)
    for (int j=0; j<2; j++) {
        process = Runtime.getRuntime().exec(sargs[j]);
        stderr = process.getErrorStream();
        reader = new BufferedReader (new InputStreamReader(stderr));
        bstring = new StringBuilder();
        while ((line=reader.readLine()) != null)
            bstring.append(line);
        message=bstring.toString();
        if (!message.isEmpty()) {
            System.err.println("Error: "+message);
            reader.close();
            return;
        }
    }

long exec_time = (new Date()).getTime() - launchtime;
System.out.printf("%d repeats done in %.3f sec\n", n, exec_time*0.001);

However, the speed is not satisfying at all. 但是,速度根本不能令人满意。 In fact, it's even slower than the Python analog. 实际上,它甚至比Python类似物还要慢。 Is there something that I can improve to boost it? 有什么我可以改善的地方吗?

If running on Linux/Mac, you're better off spawning a shell process (ie, /bin/bash -i) and feed each command call into the shell to execute. 如果在Linux / Mac上运行,则最好生成一个shell进程(即/ bin / bash -i),并将每个命令调用输入到shell中以执行。 This avoids recreating the streams for each iteration. 这避免了为每次迭代重新创建流。 For this to work, you'll need to execute some end-of-output marker for each execution (ie by sending 为此,您需要为每次执行执行一些输出结束标记(例如,通过发送

"external_exe_1 arg1 -o file.tmp ; echo 'EOI EOI'"

to the shell). 到外壳)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM