我學習有效的Java並在書中,關於避免創建不必要的對象的約書亞·布洛克會談的第5項。一個示例演示可變Date對象,它們的值一經計算就不會被修改。有效的Java - 相同的方法調用時,儘管創建多個實例
這裏的「壞習慣」:
public Person(Date birthDate) {
this.birthDate = new Date(birthDate.getTime());
}
// DON'T DO THIS!
public boolean isBabyBoomer() {
// Unnecessary allocation of expensive object
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd = gmtCal.getTime();
return birthDate.compareTo(boomStart) >= 0
&& birthDate.compareTo(boomEnd) < 0;
}
的isBabyBoomer方法不必要地創建了一個新的日曆,時區和兩個Date每次被調用的時刻 - 這顯然對我來說很有意義。
這裏改進的代碼:創建只有一次,當它被初始化
public Person(Date birthDate) {
this.birthDate = new Date(birthDate.getTime());
}
/**
* The starting and ending dates of the baby boom.
*/
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();
}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0
&& birthDate.compareTo(BOOM_END) < 0;
}
日曆,時區和日期的情況。 布洛赫解釋道,這會導致顯著的性能提升,如果該方法isBabyBoomer()
被頻繁調用。
在他的機器:
壞的版本:32,000毫秒1000萬調用
改進版:130MS 1000萬調用
但是當我運行在我的系統示例中的表現是完全一樣的( 14毫秒)。 這是一個編譯器功能,實例只創建一次?
編輯:
這裏是我的標杆:
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(1960, Calendar.JANUARY, 1, 1, 1, 0);
Person p = new Person(cal.getTime());
long startTime = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
p.isBabyBoomer();
}
long stopTime = System.nanoTime();
long elapsedTime = stopTime - startTime;
double mseconds = (double) elapsedTime/1000000.0;
System.out.println(mseconds);
}
乾杯,馬庫斯
您可能需要閱讀:http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – 2013-02-09 21:33:08
與現代JVM我希望有與新推出的多種genreation GC技術沒有什麼不同。 – 2013-02-09 21:36:12
是否**你也調用它1000萬次(循環中)(檢查循環前後的時間)?如果你只運行過一次,它們都會創建一次對象(雖然在不同的時間),但實際上並不多。 – Dukeling 2013-02-09 21:38:34