Efektywna Java - Ten sam czas wywołania metody pomimo tworzenia wielu instancji

Uczę się efektywnej Javy, aw punkcie 5 Księgi Joshua Bloch mówi o unikaniu tworzenia niepotrzebnych przedmiotów. Przykład demonstruje zmienne obiekty Date, które nigdy nie są modyfikowane po obliczeniu ich wartości.

Oto „zła praktyka”:

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;
}

Metoda isBabyBoomer niepotrzebnie tworzy nowy kalendarz, strefę czasową i dwie instancje daty za każdym razem, gdy jest wywoływana - i to najwyraźniej ma dla mnie sens.

A tutaj ulepszony kod:

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;
}

Instancje kalendarza, strefy czasowej i daty są tworzone tylko raz, gdy są inicjowane. Bloch wyjaśnia, że ​​powoduje to znaczny wzrost wydajności, jeśli metodaisBabyBoomer()jest często wywoływany.

Na jego maszynie:
Zła wersja: 32 000 ms dla 10 milionów wywołań
Ulepszona wersja: 130 ms dla 10 milionów wywołań

Ale kiedy uruchamiam przykłady na moim systemie, wydajność jest dokładnie taka sama (14 ms). Czy jest to funkcja kompilatora, którą instancje są tworzone tylko raz?

Edytować:
Oto mój punkt odniesienia:

    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);
}

Pozdrawiam, Markus

questionAnswers(2)

yourAnswerToTheQuestion