Pertanyaan Pertanyaan kiat kinerja


public void zero() {
    int sum = 0;
    for (int i = 0; i < mArray.length; ++i) {
        sum += mArray[i].mSplat;
    }
}

public void one() {
    int sum = 0;
    Foo[] localArray = mArray;
    int len = localArray.length;

    for (int i = 0; i < len; ++i) {
        sum += localArray[i].mSplat;
    }
}

Menurut Dokumentasi Android, di kode di atas, nol lebih lambat. Tapi saya tidak mengerti mengapa? Saya belum belajar banyak tapi saya tahu length adalah metode bukan lapangan. Jadi ketika loop mengambil nilainya, bagaimana perbedaannya dari mengambil dari variabel lokal? dan panjang array selalu diperbaiki setelah diinisialisasi. Apa yang saya rindukan?


5
2017-08-13 10:04


asal


Jawaban:


Yah, saya kira ini karena di zero, dia selalu perlu mengambil informasi dari mArray dan masuk one, dia dapat diakses. Ini berarti, zero membutuhkan dua "metode":

  1. Akses mArray
  2. Akses mArray.length

Tapi one hanya membutuhkan satu "metode":

  1. Akses len

8
2017-08-13 10:08



Dalam contoh pertama, JVM harus terlebih dahulu mengambil referensi ke array dan kemudian mengakses bidang panjangnya.

Pada contoh kedua, hanya mengakses satu variabel lokal.

Pada desktop JVMs ini umumnya dioptimalkan dan dua metode yang setara tetapi tampaknya JVM Android tidak melakukannya ... belum ...


3
2017-08-13 10:09



Ini masalah ruang lingkup. Mengakses variabel instan lebih lambat daripada variabel metode karena tidak disimpan di tempat memori yang sama. (karena variabel metode cenderung dapat diakses lebih sering).

Sama berlaku untuk len, tetapi dengan optimasi ekstra. len tidak dapat diubah dari luar metode, dan kompiler dapat melihat bahwa itu tidak akan pernah berubah. Oleh karena itu, nilainya lebih dapat diprediksi dan loop dapat lebih dioptimalkan.


2
2017-08-13 10:13



  public void zero() {
    int sum = 0;
    for (int i = 0; i < mArray.length; ++i) {
        sum += mArray[i].mSplat;
    }
}

Di sini jika Anda melihat untuk panjang larik loop dihitung untuk setiap iterasi, yang menurunkan penampilan.

  public void one() {
    int sum = 0;
    Foo[] localArray = mArray;
    int len = localArray.length;

    for (int i = 0; i < len; ++i) {
        sum += localArray[i].mSplat;
    }
}

Dalam hal ini panjang dihitung sebelum loop dan kemudian digunakan dalam loop.


2
2017-08-13 10:09