jvm 《七》對Java HotSpot VM進行基準測試 or 為什么HotSpot不能讓我的圖形代碼變得更快?

我寫了一個簡單的循環(huán)來計算一個簡單的操作,

我要研究一下他為啥這么慢?

public class Benchmark {

public static void main(String[] arg) {

long before = System.currentTimeMillis();

int sum = 0;

for (int index = 0; index < 10*1000*1000; index += 1) {

sum += index;

}

long after = System.currentTimeMillis();

System.out.println("Elapsed time: " +

Long.toString(after - before) +

" milliseconds");

}

}


HotSpot的工作原理:

? ? ? ?它首先使用解釋器運行程序。當它發(fā)現(xiàn)某些方法是“熱”時 - 也就是說,執(zhí)行了很多,要么因為它被調(diào)用很多,要么因為它包含循環(huán)很多的循環(huán) - 它會發(fā)送該方法以進行編譯。之后,將發(fā)生兩件事之一,或者在下次調(diào)用該方法時,將調(diào)用編譯版本(而不是解釋版本),或者使用編譯方法替換當前長時間運行的循環(huán),同時仍在運行。后者被稱為“堆棧替換”或OSR。

同時,如果你堅持使用/編寫這樣的微基準,你可以通過將main的主體移動到一個新方法并從main調(diào)用一次來給編譯器編譯代碼的機會,然后調(diào)用它再次出現(xiàn)在計時器中,看看HotSpot的速度有多快。

另請參閱JavaOne 2002演示文稿?S-1816如何不編寫Microbenchmark

我正在嘗試計算方法調(diào)用時間。我不希望有任何額外的工作,所以我使用一個空方法。但是當我使用HotSpot運行時,我得到的速度令人難以置信。這是我的代碼:

public class EmptyMethod {

public static void method() {

}

public static void runTest() {

long before;

long after;

// First, figure out the time for an empty loop

before = System.currentTimeMillis();

for (int index = 0; index < 1*1000*1000; index += 1) {

}

after = System.currentTimeMillis();

long loopTime = after - before;

System.out.println("Loop time: " +

Long.toString(loopTime) +

" milliseconds");

// Then time the method call in the loop

before = System.currentTimeMillis();

for (int index = 0; index < 1*1000*1000; index += 1) {

method();

}

after = System.currentTimeMillis();

long methodTime = after - before;

System.out.println("Method time: " +

Long.toString(methodTime) +

" milliseconds");

System.out.println("Method time - Loop time: " +

Long.toString(methodTime - loopTime) +

" milliseconds");

}

public static void main(String[] arg) {

// Warm up the virtual machine, and time it

runTest();

runTest();

runTest();

}

}


空方法不計算在內(nèi)。而且您還看到生成的代碼對齊對象非常敏感。

對空方法的調(diào)用正在被內(nèi)聯(lián),因此實際上沒有時間調(diào)用。編譯器在其調(diào)用站點將內(nèi)聯(lián)小方法。這減少了對小方法的調(diào)用的開銷。這對于用于提供數(shù)據(jù)抽象的訪問器方法特別有用。如果該方法實際為空,則內(nèi)聯(lián)將完全刪除該調(diào)用。

代碼生成到內(nèi)存中并從那里執(zhí)行。代碼在內(nèi)存中的布局方式對其執(zhí)行方式有很大影響。在我的機器上的這個例子中,聲稱調(diào)用該方法的循環(huán)更好地對齊,因此比試圖計算運行空循環(huán)所需多長時間的循環(huán)運行得更快,所以我得到負數(shù)?methodTime-loopTime。

好的,所以我會在方法的主體中放入一些隨機代碼,因此它不是空的,并且內(nèi)聯(lián)不能只刪除它。這是我的新方法(并且調(diào)用站點更改為調(diào)用方法(17)):

public static void method(int arg){

int value = arg + 25;

}


HotSpot編譯器足夠智能,不會為死變量生成代碼。

在上面的方法中,從不使用局部變量,因此沒有理由計算其值。因此,方法體再次為空,當代碼被編譯時(并且內(nèi)聯(lián),因為我們刪除了足夠小的代碼以便內(nèi)聯(lián)),它又變成了一個空方法。

對于那些不習慣處理優(yōu)化編譯器的人來說,這可能是令人驚訝的,因為他們可以非常聰明地發(fā)現(xiàn)和消除死代碼。它們偶爾可能相當愚蠢,所以不要指望編譯器對代碼進行任意優(yōu)化。

死代碼消除也擴展到控制流程。如果編譯器可以在測試中看到特定的“變量”實際上是常量,則可以選擇不編譯永遠不會執(zhí)行的分支的代碼。這使得微基準測試“足夠棘手”以實際計算您認為您的計時時間變得棘手。

死代碼消除在實際代碼中非常有用。并不是說人們故意寫死代碼;?但是,由于內(nèi)聯(lián)常常(例如,方法的實際參數(shù))替換變量,使得某些控制流失效,編譯器通常會發(fā)現(xiàn)死代碼。

我正在嘗試對對象分配和垃圾收集進行基準測試。所以我有上面的那個,但方法的主體是:

public static void method(){

Object o = new Object();

}


這是HotSpot存儲管理器的最佳案例。你會得到不切實際的數(shù)字。

您正在分配不需要初始化的對象,并立即將它們放在地板上。(不,編譯器不夠聰明,無法優(yōu)化分配。)真正的程序確實分配了相當數(shù)量的短期臨時對象,但它們也比這個簡單的測試程序更長時間地保留了一些對象。HotSpot存儲管理器為保留更長時間的對象執(zhí)行更多工作,因此請注意嘗試將此類測試中的數(shù)字擴展到實際系統(tǒng)。

我有一個圖形密集型或基于GUI的程序。為什么HotSpot不能讓我的圖形代碼變得更快?

圖形程序?qū)⒋罅繒r間花在本機庫中。

Java應(yīng)用程序的整體性能取決于四個因素:

應(yīng)用程序的設(shè)計

虛擬機執(zhí)行Java字節(jié)碼的速度

執(zhí)行基本功能任務(wù)的庫執(zhí)行的速度(以本機代碼表示)

底層硬件和操作系統(tǒng)的速度

虛擬機負責字節(jié)代碼執(zhí)行,存儲分配,線程同步等。與虛擬機一起運行的是本機代碼庫,它們通過操作系統(tǒng)處理輸入和輸出,尤其是通過窗口系統(tǒng)的圖形操作。在這些本機代碼庫中花費大量時間的程序?qū)⒉粫吹剿鼈冊贖otSpot上的性能提高與花費大部分時間執(zhí)行字節(jié)代碼的程序一樣多。

關(guān)于本機代碼的這種觀察適用于您恰好與應(yīng)用程序一起使用的其他本??機庫或任何本機代碼庫。

您對HotSpot或任何虛擬機進行基準測試的建議

這里最好的答案是使用真實的應(yīng)用程序進行基準測試,因為它們是唯一能夠產(chǎn)生真正差異的應(yīng)用程序。如果無法做到這一點,請使用標準SPEC基準測試,然后使用其他備受推崇的行業(yè)基準測試。應(yīng)避免使用微量標記,或至少要謹慎使用。微基準測試由于優(yōu)化效果而給出誤導性答案是很常見的。


---------------------

作者:a_Ygygs_Dxdsr_XdMss

來源:CSDN

原文:https://blog.csdn.net/weixin_42749765/article/details/87454013

版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容