views:

52

answers:

2

Is there a way to execute a command in java that doesn't suffer from the startup overhead (slowness) of using ProcessBuilder?

More detail: I am using im4java which is a java library that internally uses ProcessBuilder to execute imagemagick's programs. It is slow. I have created a small unit test that shows that ProcessBuilder (not im4java) is the problem. The slowness is the startup overhead of using ProcessBuilder. I have found posts around the internet saying processbuider has overhead so its not just me saying it does.

List<String> commands = new ArrayList<String>();
commands.add("C:\\PROGRA~2\\ImageMagick-6.6.4-Q16\\convert.exe");
commands.add("dog.jpg");
commands.add("output.jpg");
ProcessBuilder processBuilder = new ProcessBuilder(commands);
Process start = processBuilder.start();
start.waitFor();
A: 
Runtime.getRuntime().exec(...)  

can be used to run an external command. You can turn your List into a command array or a string to pass to exec().

RD
Thanks but I have done that too. It seems to have the same overhead. Do you know different? (my test case could just be misleading)
Plaudit Design - Web Design
Nope. as another commenter noted, you are already using the preferred method of executing another application. If this isn't faster, there is probably not much you can do.
RD
`Runtime.getRuntime().exec()` uses `ProcessBuilder`.
Jonathan
A: 

This is not recommended, but you could write a JNI library to do the same thing that ProcessBuilder is doing. Perhaps yours would be faster, but I wouldn't count on it, plus you would lose cross-platform compatibility.

How slow are we talking here? I'm using ProcessBuilder myself for running Git commands (haven't had a chance to look into JGit yet), and it seems snappy enough. You may have better luck on Linux, as the overhead may actually be in Windows heavyweight process creation.

Jonathan
One second in Windows and two seconds in linux. (The windows machine is much better hardware then the linux machine) When I run the program directly (not form java) it runs in milliseconds.
Plaudit Design - Web Design
I just looked at the `ProcessBuilder` and `Runtime.exec()` code. `Runtime.exec()` uses `ProcessBuilder`, and the only likely slowdown in `ProcessBuilder` is converting a list to an array of strings, and then copying that array. If you really need more speed, you'll likely need to write your own native implementation.
Jonathan