我有一種方法,第一次執行需要很多時間。但經過多次調用後,花費的時間減少了大約30倍。所以,爲了讓我的應用程序更快地響應用戶交互,我在初始化應用程序時用一些示例數據「預熱」了此方法(5次)。但是這會增加應用程序的啓動時間。
我讀過,JVM的可以優化和編譯我的Java代碼到本機,從而加快速度。 我想知道 - 也許有一些方法可以明確告訴JVM,我希望在啓動應用程序時編譯此方法?有沒有辦法告訴JVM在處理之前優化我的代碼?
回答
JVM在運行時執行JiT(即時)優化。這意味着它可以分析代碼的執行情況並進行優化以提高運行時性能。這發生在運行時間。如果您看到方法在執行幾次後變得更快,那可能是因爲JiT優化(除非您的分析有缺陷,並且方法因爲數據變得更簡單而變得更快)。如果你的分析是正確的,編譯爲本地可能會傷害你,因爲你將不再獲得運行時優化。
我們可以看到該方法嗎?您可能可以更快地完成工作,而無需擔心JVM的工作方式。您應該隔離確切地說哪裏是最昂貴的操作。您還應該驗證這不是某種垃圾收集問題。也許這種方法很好,但是有一個GC正在咀嚼時間,當它完成時,你的方法以可接受的速度運行。
的JIT優化工作這麼好,正是因爲他們優化實際上做什麼你的代碼,而不是它可能在不同的情況下做的。
由於輸入數據不同,甚至有可能JITted代碼在不同的運行中不同。甚至在情況發生變化時甚至可以不止一次地重新優化。
換句話說:沒有真實數據,JVM將無法很好地優化代碼。 (即它只能做「靜態」優化)
但到最後,如果你要這麼高的改進(30X是很多!),它很可能是它要麼
- 不代碼,但其他東西(如文件或數據庫緩存)
- 非常在源級別的非最佳代碼。 (像一些重計算,可以去緊密的循環出)
編輯:
看你的代碼,在一個大循環上Literas.prepareLiteras()
後,你一直打電話path.contains(p)
與不同點,但相同的路徑。 SimplePath.contains()
每次調用時會創建一個邊界形狀,因此您最終會一次又一次創建相同的形狀。這是應該從內部循環中撤出的一個主要例子。
我不認爲JIT可以優化整個方法,但在某些極端情況下,它可能會將getShape()
轉換爲專用於單個路徑的內容,併爲下一個路徑再次重新編譯。不是很好的使用JVM智能,呃?
如果使用Sun JVM,則JIT編譯的閾值有所不同,具體取決於您使用的是客戶端還是服務器JVM。對於客戶端來說,對一個方法來說是1500個調用,對於服務器來說是10000個。你可以使用JVM參數-XX:CompileThreshold=100
將其更改爲非常低的值。
儘管如此低的門檻不會有利於您的全球業績。我只建議使用它來測試通過預熱來改善性能是否受到JIT的影響。
我從來沒有看到因預熱而導致係數30的改善,這是由於JIT優化。然而。這總是由於一些緩存。
如果您有64位操作系統,則可以嘗試在64位JVM上運行此操作。
在Oracle的實現中有兩個版本的JVM:客戶端VM和服務器VM。在32位Windows上,客戶端VM是默認值。在64位Windows上,服務器虛擬機是默認的。
客戶端和服務器虛擬機之間的區別在於它們如何進行調整:服務器虛擬機比客戶端虛擬機執行更積極的優化(並且在早期完成)。服務器虛擬機爲長時間運行的進程優化了設置。客戶端虛擬機具有針對桌面使用進行了優化的默認設置:預先進行的優化較少,但啓動速度更快。
我在計算密集型程序中遇到了主要的速度差異;與32位JVM相比,這些有時在64位JVM上運行速度快兩倍。
大多數情況下,我會同樣使用hvgotcodes,但也有可能這個問題不是JVM優化,但是在通過磁盤獲得的數據的最初幾次運行之後,現在仍在緩存中,或者前幾次仍然是加載和初始化類,但之後,他們都在記憶中。
- 1. 有沒有辦法告訴Eclipse在構建之前「保存所有」?
- 2. PHP錯誤處理:我的代碼沒有經過優化
- 3. 有沒有什麼辦法可以優化這段代碼?
- 4. JavaScript代碼很慢(JQuery)。有沒有辦法優化它?
- 5. 有沒有辦法在VisualStudio中調試預處理代碼
- 6. Flex:有沒有辦法告訴所有代碼何時停止執行?
- 7. 有沒有辦法告訴我的UIView從哪個nib醒來?
- 8. 有沒有辦法告訴用戶代理「像這樣的標籤」?
- 9. 散列函數:有沒有辦法進一步優化我的代碼?
- 10. 有沒有辦法告訴哪個JavaScript文件包含事件處理程序?
- 11. 有沒有辦法在處理之前接收所有數據包?
- 12. 有沒有辦法告訴你的python文件在哪裏?
- 13. 有沒有辦法在包含之後和解析之前查看php代碼?
- 14. 有沒有人告訴我什麼是錯,此代碼
- 15. 有沒有辦法告訴maven在哪裏放置文物?
- 16. 在推送Mercurial之前,有沒有辦法檢查某人的代碼?
- 17. 有沒有辦法在代碼
- 18. 有沒有辦法告訴HtmlUnit抓住所有依賴
- 19. 有沒有辦法告訴Doxygen忽略(所有)命名空間?
- 20. 有沒有辦法告訴如果Android設備是隻有wifi?
- 21. 有沒有辦法告訴gvim的實例,而不使用--servername?
- 22. 有沒有辦法告訴MainMenu的寬度?
- 23. 在Jupyter筆記本接口中,有沒有辦法在選定的代碼行之前運行所有代碼?
- 24. 有沒有辦法讓當前的UIEvent被處理?
- 25. 有沒有辦法告訴DWR忽略一個懶惰初始化的字段?
- 26. 有沒有辦法強制JVM在單個處理器或Core上運行
- 27. 芹菜工人有沒有辦法告訴經紀人「在我告訴你之前不要給我下一個信息」
- 28. 有沒有辦法在FlashDevelop中重新格式化代碼?
- 29. 有沒有辦法在完全加載之前告訴.ogg視頻的文件大小?
- 30. Java編譯 - 有沒有辦法告訴編譯器忽略我的部分代碼?
您是否確定它在被完全因爲JVM優化而被調用多次後性能更好。根據你的方法做什麼,它也可能是其他的東西 - 例如,磁盤或數據庫緩存...... – 2011-01-07 14:22:24
@Rogach:你不能先優化你的方法嗎?它做什麼樣的東西? – Gugussee 2011-01-07 14:24:47
這個方法究竟做什麼? – Cratylus 2011-01-07 14:24:57