Java Virtual Machine - Ottimizzazioni JIT

In questo capitolo, impareremo a conoscere le ottimizzazioni JIT.

Metodo Inlining

In questa tecnica di ottimizzazione, il compilatore decide di sostituire le chiamate di funzione con il corpo della funzione. Di seguito è riportato un esempio per lo stesso:

int sum3;

static int add(int a, int b) {
   return a + b;
}

public static void main(String…args) {
   sum3 = add(5,7) + add(4,2);
}

//after method inlining
public static void main(String…args) {
   sum3 = 5+ 7 + 4 + 2;
}

Usando questa tecnica, il compilatore salva la macchina dall'overhead di effettuare qualsiasi chiamata di funzione (richiede il push e il popping dei parametri nello stack). Pertanto, il codice generato viene eseguito più velocemente.

L'inlining del metodo può essere eseguito solo per funzioni non virtuali (funzioni che non vengono sovrascritte). Considera cosa accadrebbe se il metodo "add" fosse ignorato in una sottoclasse e il tipo di oggetto contenente il metodo non fosse noto fino al runtime. In questo caso, il compilatore non saprebbe quale metodo incorporare. Ma se il metodo fosse contrassegnato come "finale", il compilatore saprebbe facilmente che può essere inline perché non può essere superato da nessuna sottoclasse. Si noti che non è affatto garantito che un metodo finale sia sempre integrato.

Eliminazione del codice irraggiungibile e morto

Il codice irraggiungibile è un codice che non può essere raggiunto da nessun possibile flusso di esecuzione. Considereremo il seguente esempio:

void foo() {
   if (a) return;
   else return;
   foobar(a,b); //unreachable code, compile time error
}

Anche il codice morto è un codice irraggiungibile, ma in questo caso il compilatore sputa un errore. Invece, riceviamo solo un avviso. Ogni blocco di codice come costruttori, funzioni, try, catch, if, while, ecc., Ha le proprie regole per il codice non raggiungibile definite nella JLS (Java Language Specification).

Piegatura costante

Per comprendere il concetto di piegatura costante, vedere l'esempio seguente.

final int num = 5;
int b = num * 6; //compile-time constant, num never changes
//compiler would assign b a value of 30.