2010-10-26 2 views
6

Я заметил, что время запуска минимального консольного приложения в Java чуть более 100 мс на моей машине по сравнению с 1 мс эквивалентного приложения C. Хотя в большинстве случаев это не проблема, я хотел бы узнать, есть ли способ уменьшить это время, потому что мне нужно написать приложение, которое будет выполняться много раз (скажем, в цикле внутри сценария bash).Есть ли способ уменьшить время запуска консольного Java-приложения?

+0

дубликат http://stackoverflow.com/questions/1316056/how-to-reduce-scala-java-startup-overhead - обязательно используйте '-client' – sfussenegger

+0

Спасибо за ссылку. К сожалению, клиент не сокращает время запуска на моей машине. – vitaut

ответ

2

Вы просите «ахиллесова пята» Java. На самом деле это не так много. Последняя версия Java будет самой результативной, они работают годами на that issue.

Во всяком случае, запуская ту же программу несколько раз, вы заметите, что после первого запуска следующий намного быстрее. Я думаю, что это происходит из механизма кэширования ОС.

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

100 мс не слишком звучит, но может быть неприемлемым в вашем случае.

+0

К сожалению, Java Quick Starter применяется только к Windows. – vitaut

+0

Действительно, время запуска улучшается для последующих запусков, но 100 мс - это улучшенное время. Я думал начать какой-то фоновый процесс при первом запуске и использовать его в последующих запусках, но пока не уверен, как это сделать. – vitaut

+1

Вы можете написать приложение, которое прослушивает TCP-сокет, получая некоторые команды и возвращая результат в виде обычного текста. Подключите к сокету netcat из вашего скрипта. Вот и все (почти!). – PeterMmm

2

Так вот некоторые подробности о решении, которое я использовал.

Начиная с этой тривиальной программы (Helloworld.java), которая занимает около 100 мс для выполнения:

class HelloWorld { 
    public static void main(String[] args) { 
     System.out.println("Hello, world!"); 
    } 
} 

$ javac HelloWorld.java 
$ time java HelloWorld 
Hello, world! 

real 0m0.109s 
user 0m0.030s 
sys  0m0.030s 

я преобразовал его в тривиальное сервер:

import java.io.*; 
import java.net.*; 

class HelloWorldThread extends Thread { 
    private Socket socket; 

    public HelloWorldThread(Socket s) { 
     super("HelloWorldThread"); 
     socket = s; 
    } 

    public void run() { 
     try { 
      PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
      out.println("Hello, world!"); 
      out.close(); 
      socket.close(); 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class HelloWorld { 
    public static void main(String[] args) { 
     try { 
      ServerSocket serverSocket = new ServerSocket(30281); 
      while (true) 
       new HelloWorldThread(serverSocket.accept()).start(); 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

запустить его один раз и использовать netcat для подключитесь к нему (спасибо PeterMmm за идею), которая привела к времени выполнения всего 3 мсек:

$ javac HelloWorld.java 
$ java HelloWorld & 
$ time nc localhost 30281 
Hello, world! 

real 0m0.003s 
user 0m0.000s 
sys  0m0.000s 
1

Скомпилируйте свой код в собственный код, используя GCJ. Немного помогу, не ожидайте слишком многого.

+0

+1, потому что он дает ускорение 2,5 раза. Однако он по-прежнему занимает 40 мс, что в 10 раз медленнее, чем решение netcat. – vitaut

1

А может быть, java - не лучший инструмент для работы? Использование подхода клиент-сервер только по соображениям производительности кажется мне очень плохой идеей. Вы вводите дополнительную сложность и точки отказа. Что делать, если серверные сбои или порт tcp уже приняты и т. Д.?

+0

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

+0

Если язык не может быть изменен, я бы предложил использовать именованный канал insted для tcp-сокета. Это более простое и надежное решение. –

Смежные вопросы