2017-03-24 20 views
0

哪個性能比較好?什麼是java字節碼性能getfield vs invokevirtual

我問這個問題沒有測試,因爲我很懶。現在經過測試,它顯示getMethod稍快於點域

Integer xj = x.getJ();` 

Integer yj = x.j; 

下面是Java字節碼我沒有後反編譯

L5 { 
    aload1 
    invokevirtual testj/ByteCodeTest getJ(()Ljava/lang/Integer;); 
    astore4 
} 
L6 { 
    aload1 
    getfield testj/ByteCodeTest.j:java.lang.Integer 
    astore5 
} 

這裏我正在測試的代碼:

public void setPoint(){ 
    point=System.currentTimeMillis(); 
    System.out.println("point"+point); 
} 
public void comparePoint(){ 
    long endPoint=System.currentTimeMillis(); 
    System.out.println("endPoint"+endPoint); 
    System.out.println("inteval"+(endPoint-point)); 
} 
int count =2000000000; 
public void test22(){ 
    ByteCodeTest x = new ByteCodeTest(); 
    setPoint(); 
    for(int i=0;i<count;i++){ 
     int yy= x.i+1; 
    } 
    comparePoint(); 
    setPoint(); 
    for(int i=0;i<count;i++){ 
     int yy=x.getI()+1; 
    } 
    comparePoint(); 
} 

下面是代碼輸出:

point1490454906205 

endPoint1490454907447 

inteval1242 

point1490454907448 

endPoint1490454908666 

inteval1218 

這意味着getMethod比點域

+1

爲什麼?出於性能原因你打算選擇一個嗎? – Kayaman

+2

如果在這個分鐘級別的性能差異對您有影響,您應該使用較低級別的編程語言,而不是使用Java – ControlAltDel

回答

0

當你使用一個getter,你叫從而降低了性能,而不僅僅是訪問領域的功能稍快。如果你在第一種情況下查看你的字節代碼,你應該在這裏調用getJ的定義。

5

字段訪問比方法調用要快,但除非您在緊密的循環中編寫對性能非常敏感的代碼,否則使用其中一個的決定是設計,而不是性能。

添加JIT的混合,你可能沒有得到任何優勢來自直接字段訪問。

2

字節碼是不同的,但最終,JIT將通過內聯內聯來優化訪問。與編寫代碼時的程序員不同,JIT可以隨時準確地告訴程序員是否覆蓋了getter。相信這個JIT,從長遠來看性能是相同的。

什麼不相同,是可維護性。使用getter方法可以使用擴展/修改的邏輯覆蓋getter(另一方面,這樣做的代價會使getter多態,導致性能降低,而直接字段訪問甚至不可能)。

使用直接字段訪問沒有任何優勢,但在代碼稍後演變時會遇到很多隱患。