Allocazione di memoria durante il richiamo di una sequenza di funzioni in Java

2

Un metodo getReminder accetta due interi e restituisce r = (a^5)%m . Questo metodo si basa su due BigInteger numeri BigInteger.valueOf(a).pow(5) e BigInteger.valueOf(m) , ma BigInteger non è mai stato dichiarato. Allo stesso tempo, int è stato dichiarato due volte anche se è sufficiente solo un int . Mi rendo conto che int non costa molto spazio, voglio solo capire meglio i meccanismi.

int myRemainder = getReminder(1000000, 42);
.............
private int getReminder(int a, int m){
int r =BigInteger.valueOf(a).pow(5).remainder(BigInteger.valueOf(m)).intValue(); 
     return r;
}

BigInteger è stato creato dietro le quinte? Non è necessario dichiarare int due volte?

    
posta sixtytrees 30.06.2016 - 00:11
fonte

1 risposta

3

Mentre è più veloce digitare una catena di chiamate come questa può essere difficile da capire. L'ottimizzatore ottimizzerà rapidamente la catena di chiamate, ma fornirà uno stack di errori migliore. È meglio codificare la leggibilità. Come illustrato di seguito, la codifica con una chiamata di funzione per riga produce la risposta.

Dal Javadoc di BigInteger.

static BigInteger valueOf(long val) Returns a BigInteger whose value is equal to that of the specified long.

Il codice per questa funzione includerà la creazione di un nuovo BigInteger da restituire. Questi sono valori di ritorno temporanei che non vengono mai memorizzati nella variabile, quindi non c'è alcuna dichiarazione. I valori temporanei verranno archiviati nello stack se è richiesta la memorizzazione.

Vedo una dichiarazione int, int r . int è anche usato per specificare il tipo di ritorno, così come i tipi di parametro del metodo. Sarebbe possibile evitare la dichiarazione di r e solo restituire il risultato della catena di chiamate. L'ottimizzatore potrebbe evitare la creazione di r e restituire semplicemente il valore.

Come regola generale, l'ottimizzatore può creare variabili temporanee e ignorare le variabili dichiarate come necessario. Applicare la Legge di Demetra e dichiarare le variabili come richiesto ti darà un'idea delle variabili richieste. Questo è un modo possibile per analizzare inizialmente questo codice:

private int getReminder(int a, int m) {
    BigInteger tmp1 = BigInteger.valueOf(a);
    tmp1 = tmp1.pow(5);
    BigInteger tmp2 = BigInteger.valueOf(m); 
    tmp1 = tmp1.remainder(tmp2);
    int r = tmp1.intValue(); 
    return r;
}

Tutte e tre le variabili, tmp1, tmp2 e r, saranno allocate nello stack. In una lingua come c l'ottimizzazione di primo livello sarebbe utilizzare i registri per le variabili. Ciò eliminerebbe la necessità di allocare memoria per loro ed evitare il sovraccarico di lettura e scrittura in memoria.

È possibile ottenere i dump del codice byte del codice che mostreranno come sono state effettivamente eseguite le allocazioni. Questo potrebbe cambiare un diverso livello di ottimizzazione. Se viene richiamato, il compilatore JIT può ulteriormente ottimizzare il codice.

    
risposta data 30.06.2016 - 01:33
fonte

Leggi altre domande sui tag