在 Java 中加速外部调用
Speed-up external call in Java
我在 JAVA 中有一个程序,每次启动时需要调用其他两个外部可执行文件(用 C++ 编写)数千次。它们每个的实际计算时间实际上是毫秒,因此整个程序的瓶颈是对临时文件的调用和 write/read(external_exe_2 只能从文件读取其输入)。我还需要检查是否没有发生错误。
我有以下基准测试程序来衡量外部调用的性能:
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);
然而,速度一点都不令人满意。事实上,它甚至比 Python 模拟还要慢。有什么我可以改进的地方吗?
如果 运行 在 Linux/Mac 上,你最好生成一个 shell 进程(即 /bin/bash -i)并将每个命令调用提供给 shell执行。这避免了为每次迭代重新创建流。为此,您需要为每次执行执行一些输出结束标记(即通过发送
"external_exe_1 arg1 -o file.tmp ; echo 'EOI EOI'"
到 shell).
我在 JAVA 中有一个程序,每次启动时需要调用其他两个外部可执行文件(用 C++ 编写)数千次。它们每个的实际计算时间实际上是毫秒,因此整个程序的瓶颈是对临时文件的调用和 write/read(external_exe_2 只能从文件读取其输入)。我还需要检查是否没有发生错误。
我有以下基准测试程序来衡量外部调用的性能:
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);
然而,速度一点都不令人满意。事实上,它甚至比 Python 模拟还要慢。有什么我可以改进的地方吗?
如果 运行 在 Linux/Mac 上,你最好生成一个 shell 进程(即 /bin/bash -i)并将每个命令调用提供给 shell执行。这避免了为每次迭代重新创建流。为此,您需要为每次执行执行一些输出结束标记(即通过发送
"external_exe_1 arg1 -o file.tmp ; echo 'EOI EOI'"
到 shell).