簡體   English   中英

Java - System.out 對性能的影響

[英]Java - System.out effect on performance

我見過這個問題,它有點相似。 我想知道這是否真的是影響我的應用程序性能的一個重要因素。 這是我的場景。

我有這個 Java 網絡應用程序,它可以從每行從上到下讀取的電子表格上傳數千個數據。 我正在使用System.out.println()在服務器端顯示應用程序當前正在讀取的行。

- 我知道創建一個日志文件。 事實上,我正在創建一個日志文件,同時在服務器的提示上顯示日志。
有沒有其他方法可以在提示上打印當前數據?

它可能會對您的應用程序性能產生影響。 大小將根據您運行的硬件類型和主機上的負載而有所不同。

這可以轉化為性能方面的一些要點:

-> 就像 Rocket boy 所說的那樣, println 是同步的,這意味着您將在對象頭上產生鎖定開銷,並且可能會導致線程瓶頸,具體取決於您的設計。

-> 在控制台上打印需要內核時間,內核時間意味着 cpu 不會在用戶模式下運行,這基本上意味着您的 cpu 將忙於執行內核代碼而不是應用程序代碼。

-> 如果你已經記錄了這個,這意味着額外的內核時間用於 I/O,如果你的平台不支持異步 I/O,這意味着你的 CPU 可能會在忙等待時停止。

您實際上可以嘗試對此進行基准測試並自行驗證。

有很多方法可以避免這種情況,例如擁有一個非常快的 I/O,一台巨大的專用機器,如果您的應用程序設計不會在該控制台打印上進行多線程,則可能會在您的 JVM 選項上偏向鎖定。

就像所有關於性能的事情一樣,這一切都取決於您的硬件和優先級。

我最近正在測試(讀取和)寫入大型(1-1.5gb)文本文件,我發現:

PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(java.io.FileDescriptor.out), "UTF-8"), 512));
out.println(yourString);
//...
out.flush();

其實,幾乎250%的速度比

System.out.println(yourString);

我的測試程序首先讀取大約 1gb 的數據,對其進行一些處理並以稍微不同的格式輸出。

測試結果(在Macbook Pro上,SSD讀寫同盤):

  • 數據輸出到系統輸出 > output.txt => 1min32sec
  • 數據寫入文件在 java => 37 秒
  • 數據寫入到緩沖寫入器標准輸出 > output.txt => 36 秒

我確實嘗試了多個大小在 256-10k 之間的緩沖區,但這似乎無關緊要。

因此請記住,如果您使用 Java 創建 unix 命令行工具,其中輸出旨在定向或通過管道傳輸到其他地方,請不要直接使用 System.out!

System.out.println()

是同步的。

 public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }

如果多個線程寫入它,它的性能會受到影響。

是的,它將對性能產生巨大影響。 如果您想要一個可量化的數字,那么有很多軟件和/或方法可以衡量您自己的代碼性能。

與大多數慢速操作相比,System.out.println 非常慢。 這是因為它比其他 IO 操作在機器上放置更多的工作(並且它是單線程的)

我建議您將輸出寫入一個文件並tail該文件的輸出。 這樣,輸出仍然會很慢,但不會降低您的 Web 服務的速度。

這是一個非常簡單的程序來檢查 System.out.println 的性能並將其與乘法運算進行比較(您可以使用其他特定於您的要求的運算或函數)。

public class Main{

 public static void main(String []args) throws InterruptedException{
             
    
    long tTime = System.nanoTime();
    long a = 123L;
    long b = 234L;
    
    long c  = a*b;
    long uTime = System.nanoTime();
    
    System.out.println("a * b = "+ c +". Time taken for multiplication =  "+ (uTime - tTime) + " nano Seconds");
    
    long vTime = System.nanoTime();
    System.out.println("Time taken to execute Print statement : "+ (vTime - uTime) + " nano Seconds");
    
 }
}

輸出取決於您的機器及其當前狀態。

這是我得到的: https : //www.onlinegdb.com/online_java_compiler

a * b = 28782. Time taken for multiplication =  330 nano Seconds                                                                                                                     
Time taken to execute Print statement : 338650 nano Seconds 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM