2013-08-13 19 views
5
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; 
    } 
} 

Secondo il codice Android documentation, nel codice precedente, zero è più lento. Ma non capisco perché? beh non ho imparato molto in profondità, ma come so length non è un metodo. Quindi, quando il ciclo recupera il suo valore, in che modo è diverso dal recupero dalla variabile locale? e la lunghezza dell'array è sempre fissa una volta inizializzata. Cosa mi manca?Suggerimenti sulle prestazioni domande

+0

Fino a quando il JIT non ottimizza il codice, il primo esempio ha più lavoro da fare su ciascun ciclo. Una volta che il codice è stato compilato, dovrebbe essere lo stesso. (È su OpenJDK) –

risposta

8

Beh, suppongo che questo sia dovuto al numero , che deve sempre recuperare le informazioni da mArray e nel numero one, l'ha accessibile. Ciò significa, zero ha bisogno di due "metodi":

  1. accesso Marray
  2. accesso mArray.length

Ma one necessita di un solo "metodi":

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

Qui, se si guarda la lunghezza del ciclo per loop viene calcolata per ogni iterazione, che degrada la prestazione .

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

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

In questo caso la lunghezza viene calcolata prima per ciclo e quindi utilizzata nel ciclo.

3

Nel primo esempio, la JVM deve prima recuperare il riferimento alla matrice e quindi accedere al relativo campo della lunghezza.

Nel secondo esempio, accede solo a una variabile locale.

Su JVM desktop Questo è generalmente ottimizzato ed i due metodi sono equivalenti ma sembra che JVM di Android non lo fa ... eppure ...

2

Si tratta di una questione di portata. L'accesso a una variabile di istanza è più lento di una variabile di metodo poiché non è memorizzato nelle stesse posizioni di memoria. (perché è probabile che le variabili di metodo siano accessibili più spesso).

Lo stesso vale per len, ma con un'ottimizzazione aggiuntiva. len non può essere modificato dall'esterno del metodo e il compilatore può vedere che non cambierà mai. Pertanto, il suo valore è più prevedibile e il ciclo può essere ulteriormente ottimizzato.

Problemi correlati