2010-10-15 7 views
2

Existe-t-il un moyen d'exécuter une commande dans java qui ne souffre pas du temps de démarrage (lenteur) de l'utilisation de ProcessBuilder?exécuter une commande externe dans java

Plus de détails: J'utilise im4java qui est une bibliothèque Java qui utilise en interne ProcessBuilder pour exécuter les programmes de imagemagick. C'est lent. J'ai créé un petit test unitaire qui montre que ProcessBuilder (pas im4java) est le problème. La lenteur est la surcharge de démarrage de l'utilisation de ProcessBuilder. J'ai trouvé des messages sur Internet disant que le processus de traitement avait des frais généraux, donc ce n'est pas seulement moi qui le dis.

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

Les performances sont-elles vraiment un problème ou simplement «ennuyeuses» lors des tests? L'utilisation de ProcessBuilder est encouragée plutôt que l'utilisation de Runtime.exec() pour plusieurs bonnes raisons (http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html). –

+0

Oui, les performances sont un problème. Je me suis trompé cependant sur combien de temps ProcessBuilder dégrade la performance. Cela n'ajoute pas grand chose. Il semble juste qu'il y ait des ralentissements dans quelques endroits, donc c'est additionnel. –

Répondre

0

Ceci n'est pas recommandé, mais vous pouvez écrire une bibliothèque JNI pour faire la même chose que ProcessBuilder. Peut-être que le vôtre serait plus rapide, mais je ne compterais pas dessus, et vous perdriez la compatibilité multiplateforme.

Combien de temps parlons-nous ici? J'utilise moi-même ProcessBuilder pour exécuter des commandes Git (je n'ai pas encore eu l'occasion de regarder dans JGit), et cela semble assez rapide. Vous pouvez avoir plus de chance sur Linux, car les frais généraux peuvent être dans la création de processus lourds de Windows.

+0

Une seconde sous Windows et deux secondes sous Linux. (La machine Windows est un matériel bien meilleur que la machine Linux) Quand je lance le programme directement (pas sous Java), il s'exécute en millisecondes. –

+0

Je viens de regarder le code 'ProcessBuilder' et' Runtime.exec() '. 'Runtime.exec()' utilise 'ProcessBuilder', et le seul ralentissement probable de' ProcessBuilder' est la conversion d'une liste en un tableau de chaînes, puis la copie de ce tableau. Si vous avez vraiment besoin de plus de vitesse, vous aurez probablement besoin d'écrire votre propre implémentation native. – Jonathan

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

peut être utilisé pour exécuter une commande externe. Vous pouvez transformer votre liste en un tableau de commandes ou une chaîne à transmettre à exec().

+0

Merci, mais je l'ai fait aussi. Il semble avoir les mêmes frais généraux. Connaissez-vous différent? (mon test peut être trompeur) –

+0

Non. Comme l'a noté un autre intervenant, vous utilisez déjà la méthode préférée pour exécuter une autre application. Si ce n'est pas plus rapide, il n'y a probablement pas grand-chose à faire. –

+0

'Runtime.getRuntime(). Exec()' utilise 'ProcessBuilder'. – Jonathan