我有一个Java程序,需要调用同一个外部可执行文件6次。 此可执行文件生成一个输出文件,一旦所有 6 次运行完成,我就会将这些文件"合并"在一起。 我确实有一个 for 循环,我在其中运行代码,等待外部可执行文件的第一次运行结束,然后我再次调用它,等等。
我发现这非常耗时,平均运行 52.4 次需要 6 秒...... 我认为通过一次运行外部可执行文件 6 次来加快速度非常容易,特别是因为它们不相互依赖。 我用ExecutorService
和Runnable
等来实现这一点。
通过我目前的实现,我减少了大约 ~5 秒的时间,使其速度仅提高了 ~11%。
以下是一些(简化的(代码,解释了我在做什么:
private final List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
....
private void setUpThreadsAndRun() {
ExecutorService executor = Executors.newFixedThreadPool(6);
for (int i = 0; i < 6; i++) {
//create the params object
tasks.add(Executors.callable(new RunThread(params)));
}
try {
executor.invokeAll(tasks);
} catch (InterruptedException ex) {
//uh-oh
}
executor.shutdown();
System.out.println("Finished all threads!");
}
private class RunThread implements Runnable {
public RunThread(ModelParams params) {
this.params = params;
}
@Override
public void run()
{
//NOTE: cmdarray is constructed from the params object
ProcessBuilder pb = new ProcessBuilder(cmdarray);
pb.directory(new File(location));
p = pb.start();
}
}
我希望有一种更有效的方法可以做到这一点......或者,也许我尝试一次运行此过程 6 次来"阻塞"计算机的资源。 此过程确实涉及文件 I/O,并写入大小约为 30mb 的文件。
可执行文件分叉 6 次将获得性能提升的唯一情况是,如果您至少有 6 个 CPU 内核并且您的应用程序受 CPU 限制 - 即主要执行处理器操作。 由于每个应用程序写入一个 30mb 的文件,听起来它正在执行大量 IO,并且应用程序是 IO 绑定的 - 受到硬件为 IO 请求提供服务的能力的限制。
为了加快程序速度,您可以尝试 2 个并发进程,看看是否得到改进。 但是,如果您的程序是 IO 绑定的,那么您永远不会通过分叉多个副本来获得太大的速度改进。