[英]Java Optimization: Local Variable Vs Instance Variable
在Java中,如果我有很多本地對象,如果我將它們定義為實例變量,它會運行得更快嗎? 例如,如果多次調用我的func1(),比如在循環中調用,那么每次調用函數時,JVM是否會繼續實例化並垃圾收集list2? 相反,我應該重用相同的list1對象來防止垃圾收集和實例化開銷嗎?
class A {
List list1 = new ArrayList();
private void func1() {
list1.clear();
// add new objects list1
List list2 = new ArrayList();
// add new objects to list2
}
}
優化器是否足夠智能以跳過垃圾收集並自動重用對象?
GC優化不是決定Local
vs Instance
變量的正確方法。 如果需要的變量由多個實例方法使用,那么使用實例變量是有意義的。
你是對的,局部變量使用可能會增加GC活動。
在決定是使用本地變量還是實例變量之前,可能需要考慮各種用例。 性能可能因用例而異。
在Effective Java中可以找到一個很好的例子: 第5項 - “ 避免創建不必要的對象 ”
還要考慮實例變量值的線程安全性。 同一對象的兩個線程需要同步訪問實例變量數據,但在這里它始終是一個新的局部變量數據對象。
如果 - 並且僅當 - 您已經證明由於對象創建而導致GC出現問題,您應該考慮合並已證明成本高昂的對象。
對於這一點,你不必重新發明輪子的任何,您可以用Javolutions utils的實現它,例如, 高速郵件在這種情況下使用FastList.newInstance()調用:
List<Whatever> newOrReusedList = FastList.newInstance();
...以及相應的FastList.recycle(FastList)
調用,以使其可供重用。 (謝謝@JIV ,我忘了添加這一點。)
(請注意,使用javolutions Fast *類可能會導致不同的性能:它們面向可預測的性能(實時系統)而不是速度,因此可能存在用例,當它們的執行速度比java.lnag的速度慢時)
我用下面的jdk1.6寫了一個小測試程序
結果:
* dostuff為594ms(創建本地)
* dostuff2的58ms(使用實例)
public class Test {
static long counter=0;
public static void main(String[] args) {
long t1 = System.nanoTime();
Test test = new Test();
for (int i=0;i<1000000000;i++) {
test.doStuff();//or dostuff2
}
long t2 = System.nanoTime();
System.err.println((t2-t1)/1000000);
System.err.println(counter); // to check it wasnt optimised away
}
private void doStuff() {
List l = new ArrayList();
if (l!=null) {
counter++;
}
}
List l2 = new ArrayList();
private void doStuff2() {
if (l2!=null) {
counter++;
}
}
}
結果,似乎實例比使用本地更快 ,正如人們所期望的那樣。
然而,至少在我的電腦上你似乎節省了大約0.5億美元的物品,所以你需要真的需要性能增益來證明它的合理性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.