對於可以在文本編輯器中完成的小型邏輯程序,爲了跟蹤,我使用經典的System.out.println()
。Java:System.out.println()背後的原因是那麼慢?
我想你們都知道在一個大量迭代中使用它是多麼的令人沮喪。爲什麼這麼慢?它背後的原因是什麼?
對於可以在文本編輯器中完成的小型邏輯程序,爲了跟蹤,我使用經典的System.out.println()
。Java:System.out.println()背後的原因是那麼慢?
我想你們都知道在一個大量迭代中使用它是多麼的令人沮喪。爲什麼這麼慢?它背後的原因是什麼?
這與JVM沒有任何關係。將文本打印到屏幕上僅涉及操作系統在繪製字母和特別滾動時的大量工作。如果你將System.out重定向到一個文件,速度會更快。
雅,寫入控制檯的開銷很大。遠遠大於寫入文件或套接字所需的時間。此外,如果有大量的線程,他們都在同一個鎖上爭奪。我會推薦使用其他System.out.println來跟蹤。
這與Java和JVM無關,但與控制檯終端無關。在大多數操作系統中,我知道在控制檯輸出中寫入很慢。
這是非常依賴操作系統。例如,在Windows中,寫入控制檯是一項阻止操作,速度也很慢,因此將大量數據寫入控制檯會減慢(或阻止)您的應用程序。在unix類型的操作系統中,寫入控制檯的內容會被緩衝,因此您的應用可以繼續暢通無阻,並且控制檯會盡可能趕上。
有些終端比其他終端快。即使在一個操作系統內,這可能會有所不同
這看起來可能並不直接回答你的問題,但我的建議是從不使用System.out進行跟蹤(如果你的意思是通過一種調試,爲了看到你的應用程序的進步)
進行調試與System.out的問題有幾個:
一旦應用程序結束後,當您關閉控制檯,你會失去日誌
你必須刪除這些陳述一旦你的應用程序正常工作(或評論他們)。以後如果你想重新激活它們,你就必須取消註釋/再評論...繁瑣
我建議,而不是使用Log4j和「看」的日誌文件,或者用tail命令 - 那裏也就是一個Tail for Windows - 使用像LogWatcher這樣的Eclipse插件。
速度緩慢是由於每次換行或刷新時發生大量的Java本機轉換。如果迭代需要很多步驟,System.out.println()不是很有幫助。如果迭代步驟本身不重要,則可以每10或100步調用System.out.println()。您也可以將System.out包裝到BufferedOutputStream中。當然總是有選擇通過ExecutorService來同步打印。
我注意到寫入終端的一件有趣的事情(至少在Windows中)。如果窗口最小化,它實際運行速度會快多少。這絕對與Michael Borgwardt關於繪圖和滾動的答案密切相關。真的,如果你記錄足夠的時間來注意到放緩,你最好寫一個文件。
緩衝可以幫助極大。試試這個:
System.setOut(new PrintStream(new BufferedOutputStream(System.out)));
但要注意:你不會看到輸出逐步顯現,但都在一瞬間。這很好,但是如果你使用它進行調試,並且在程序終止之前程序崩潰了,在某些情況下,你可能看不到在崩潰前打印的文本。 這是因爲緩衝區在崩潰之前未刷新。它已經打印出來了,但它仍然在緩衝區中,並沒有出現在可以看到它的控制檯上。我記得這個發生在我身上,在一個令人困惑的調試會議。最好偶爾清空一下,以確保你看到它:
System.out.flush();
+1「繪製字母和特別滾動」。謝謝 – DragonBorn 2009-06-04 11:58:35