2010-10-15 3 views
2

Есть ли способ выполнить команду в java, которая не страдает из-за служебных данных запуска (медленности) использования ProcessBuilder?выполнить внешнюю команду в java

Подробнее: Я использую im4java, которая представляет собой библиотеку java, которая внутренне использует ProcessBuilder для выполнения программ imagemagick. Это медленно. Я создал небольшой единичный тест, который показывает, что проблема ProcessBuilder (а не im4java). Медленность - это накладные расходы на запуск с помощью ProcessBuilder. Я нашел сообщения по всему интернету о том, что у processbuider есть накладные расходы, поэтому не только я говорю, что это так.

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(); 
+1

Является ли производительность _really_ проблемой или просто «раздражает» во время тестирования? Использование ProcessBuilder рекомендуется, используя Runtime.exec() по нескольким причинам (http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html). –

+0

Да, это проблема. Я был не прав, хотя на сколько времени ProcessBuilder снижает производительность. Это не добавляет слишком много. Кажется, что в некоторых местах замедление замедляется, поэтому оно складывается. –

ответ

0

Это не рекомендуется, но вы можете написать библиотеку JNI, чтобы сделать то же самое, что и ProcessBuilder. Возможно, ваш будет быстрее, но я не буду рассчитывать на это, плюс вы потеряете кросс-платформенную совместимость.

Как медленно мы говорим здесь? Я использую ProcessBuilder сам для запуска команд Git (у меня еще не было возможности заглянуть в JGit), и это кажется достаточно быстрым. У вас может быть больше удачи в Linux, так как накладные расходы могут быть в самом тяжелом процессе Windows.

+0

Одна секунда в Windows и две секунды в Linux. (У машины Windows намного лучшее оборудование, чем в Linux-машине) Когда я запускаю программу напрямую (не формирую java), она запускается в миллисекундах. –

+0

Я просто посмотрел на код 'ProcessBuilder' и' Runtime.exec() '. 'Runtime.exec()' использует 'ProcessBuilder', и единственное вероятное замедление в' ProcessBuilder' - преобразование списка в массив строк, а затем копирование этого массива. Если вам действительно нужна более высокая скорость, вам, скорее всего, придется написать собственную собственную реализацию. – Jonathan

0
Runtime.getRuntime().exec(...) 

может быть использован для запуска внешней команды. Вы можете превратить свой Список в массив команд или строку, чтобы передать exec().

+0

Спасибо, но я тоже это сделал. Кажется, что у него тоже накладные расходы. Знаете ли вы другое? (мой тест может просто ввести в заблуждение) –

+0

Нет. как отметил еще один комментатор, вы уже используете предпочтительный метод выполнения другого приложения. Если это не так быстро, возможно, вы не можете многое сделать. –

+0

'Runtime.getRuntime(). Exec()' использует 'ProcessBuilder'. – Jonathan