2014-06-15 15 views
5

Io uso JMH per specificare la complessità dell'operazione. Se non hai mai lavorato con JMH, non preoccuparti. JMH lancerà il metodo estimateOperation più volte e quindi otterrà il tempo medio.Risultati cache java dei metodi

Domanda: [stretta] sarà questo programma calcola Math.cbrt(Integer.MAX_VALUE) ogni volta? O lo calcola solo una volta e restituisce il risultato in cache in seguito?

@GenerateMicroBenchmark 
public void estimateOperation() { 
    calculate(); 
} 

public int calculate() { 
    return Math.cbrt(Integer.MAX_VALUE); 
} 

Domanda: [ampio]: fa JVM mai cache il risultato dei metodi?

+0

Dove viene eseguito il comando 'calculate()'? – shmosel

risposta

8

Il metodo di ritorno il valore non è mai nella cache. Tuttavia, chiamate inutili possono essere eliminati dal compilatore JIT in fase di esecuzione a causa di alcune ottimizzazioni come costante piegatura, costante di propagazione, eliminazione morto codice, invariante di ciclo sollevamento, metodo inlining ecc

Ad esempio, se si sostituisce Math.cbrt con Math.sqrt o con Math.pow, il metodo non verrà chiamato affatto dopo la compilazione JIT, poiché la chiamata verrà sostituita da una costante. (L'ottimizzazione non funziona per cbrt, perché è un metodo raro e cade su una chiamata nativa che non è intrinseca a JVM).

+0

Non sono abbastanza sicuro di seguire ciò di cui stai parlando con le ottimizzazioni JIT ... 'Math.sqrt() 'delega anche a una chiamata nativa (dal codice che sto guardando, almeno), e non vedo perché il compilatore JIT non potrebbe anche ottimizzare' Math.cbrt() 'nella stessa maniera come 'Math.sqrt()' - la stessa tecnica dovrebbe funzionare in entrambi i casi. – awksp

+0

@ user3580294 Queste chiamate possono essere ottimizzate o meno a seconda della JVM. Se parliamo di HotSpot (la JVM più popolare inclusa in OpenJDK e Oracle JDK), 'Math.sqrt' sarà ottimizzato, perché è un [JVM intrinsico] (http://en.wikipedia.org/wiki/Intrinsic_function) , cioè il compilatore JIT non lo tratta come un metodo, ma sostituisce la chiamata con il codice di valutazione in linea. 'Math.cbrt' anche se non è un intrinseco HotSpot - semplicemente non è stato creato tale a causa della sua rarità e dell'assenza dell'istruzione CPU corrispondente. – apangin

+0

Ah, capisco. Ciò ha senso. Sembra che abbia qualche ricerca da fare ... – awksp

1

No.

In poche parole, Java non metodo di cache risultati, dal momento che i metodi possono restituire valori diversi ogni volta.

2

Sì, invocherà che ogni volta che il codice è di essere chiamato

public int calculate() { 
    return Math.cbrt(Integer.MAX_VALUE); 
} 


public double calculate(); 
    Code: 
     0: ldc2_w  #3     // double 2.147483647E9d 
     3: invokestatic #5     // Method java/lang/Math.cbrt:(D)D 
     6: dreturn  

per avere cache, è sufficiente sostituire quel numero magico da

campo finale private static

private static final double NUMBER = Math.cbrt(Integer.MAX_VALUE); 
+1

Il bytecode non spiega nulla. Per esempio. sostituisci 'cbrt' con' sqrt' e il metodo NON verrà chiamato ogni volta. La risposta dipende dal metodo che viene chiamato e dall'ambiente. Ottimizzazioni JIT ([inlining] (http://en.wikipedia.org/wiki/Inline_expansion) + [folding costante] (http://en.wikipedia.org/wiki/Constant_folding) + [intrinsics] (http: // en.wikipedia.org/wiki/Intrinsic_function)) potrebbe comportare l'eliminazione della chiamata e la sua sostituzione con una costante. – apangin

+0

@apangin quindi puoi pubblicare la tua risposta per favore? –

+0

@V_B Certo. Aggiunta una risposta espansa. – apangin

1

Risposta a domanda ristretta: dipende dall'implementazione JVM e da come viene interpretato il codice.

Risposta a una domanda di massima: No poiché, come sottolineato anche da Anubian, i metodi possono restituire valori diversi per ciascuna chiamata.

Problemi correlati