2010-10-26 66 views
6

我注意到,Java中的最小控制檯應用程序的啓動時間比我的機器上的稍微多於100毫秒,而相當於1毫秒的等效C應用程序。雖然在大多數情況下它不是問題,但我想知道是否有辦法縮短這個時間,因爲我需要編寫一個將被執行多次的應用程序(比如在bash腳本中的循環中)。有沒有減少控制檯Java應用程序啓動時間的方法?

+0

重複http://stackoverflow.com/questions/1316056/how-to-reduce-scala-java-startup-overhead-確保使用'-client' – sfussenegger 2010-10-27 22:10:43

+0

感謝您的鏈接。不幸的是,客戶端根本不能縮短我的機器的啓動時間。 – vitaut 2010-10-28 06:25:28

回答

2

您要求Java的「致命弱點」。與它沒有太大關係。最後的Java版本將是最高性能的,他們在that issue上工作多年。

無論如何多次運行相同的程序,你會注意到第一次啓動後下一個更快。我認爲這來自操作系統緩存機制。

使其更好的唯一真正方法是讓後臺運行您的應用程序,並與您的應用程序通過web服務(這是servelet容器的全部內容)進行交流。

100ms不會聽起來太多,但在您的情況下可能無法接受。

+0

不幸的是,Java快速入門只適用於Windows。 – vitaut 2010-10-26 07:58:45

+0

事實上,啓動時間對於稍後的運行而言有所提高,但是100ms是改進的時間。我正在考慮在第一次運行時啓動某種後臺進程,並在稍後的運行中使用它,但還不確定如何執行此操作。 – vitaut 2010-10-26 08:01:23

+1

您可以編寫一個在TCP套接字上偵聽的應用程序,接收一些命令並以純文本形式返回結果。從腳本中使用netcat連接到套接字。就是這樣(差不多!)。 – PeterMmm 2010-10-26 08:18:56

2

所以這裏是關於我使用的解決方案的一些細節。

從這個簡單的程序(HelloWorld.java)歷時100ms左右執行開始:

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的想法),導致執行時間只有3ms:

$ 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倍的加速。然而,它仍然需要40ms,比netcat解決方案慢10倍。 – vitaut 2010-10-27 09:13:57

1

也許java不是工作的最佳工具?使用客戶端 - 服務器方法僅僅是出於性能方面的原因,在我看來,似乎是一個非常糟糕的主意你會引入更多的複雜性和失敗點。如果服務器崩潰或TCP端口已被佔用等,該怎麼辦?

+0

如果我可以使用不同的語言,我不會問這個問題。 Java是一項要求。但是你是對的,雖然我很驚訝在Java中實現服務器是多麼容易,但還是有額外的複雜性。 – vitaut 2010-10-27 06:41:42

+0

如果語言無法更改,我會建議使用命名管道insted tcp套接字。這是更簡單,更可靠的解決方案。 – 2010-10-28 16:47:32

相關問題