2016-01-08 14 views
5

Dire che ho il seguente codice:Esiste un costo delle prestazioni per l'autoboxing di un primitivo letterale?

Map<String, Boolean> map = ... 
map.put("foo", true); 

Teoricamente, true dovranno essere autoboxed, con un conseguente lieve calo di prestazioni rispetto inserimento Boolean.TRUE. Ma dal momento che abbiamo a che fare con un valore letterale, è possibile che il compilatore sostituisca il letterale primitivo con un valore letterale in scatola, quindi non ci sono sovraccarichi di runtime aggiuntivi?

Prima che qualcuno mi attacchi, in genere opterei per il primitivo letterale per motivi di chiarezza del codice, anche se c'era un piccolo costo di prestazioni. Questa domanda è per lo più teorica.

+0

la chiave per comprendere qualsiasi domanda relativa alle prestazioni inizierà sempre con un test. Per migliorare la tua domanda, mostra un test temporale che fornisce i risultati di un'analisi delle prestazioni. Ad esempio, è possibile scrivere un ciclo temporizzato che mette le voci 100K in una mappa e stampa quanto tempo ha impiegato, e fa lo stesso per diversi argomenti a 'map.put' – activedecay

+0

Si potrebbe usare una costante' Boolean'; 'map.put (" foo ", Boolean.TRUE);' –

+0

@ElliottFrisch Lo so. La mia domanda è se sarebbe di aiuto a tutti. – shmosel

risposta

4

Sì, c'è un piccolo calo di prestazioni. Per inscatolare una primitiva, viene utilizzato il metodo valueOf() del tipo wrapper. Poiché questo è un metodo così semplice per Boolean (return x ? TRUE : FALSE;), un JIT potrebbe essere in grado di allineare in modo efficace il risultato; attualmente il compilatore Java, tuttavia, non lo fa. (L'uso di valueOf() non è richiesto da JLS, pertanto è possibile introdurre un'ottimizzazione per Boolean.)

Per altri tipi, è più complicato. Ad esempio, Integer restituisce istanze memorizzate nella cache per valori vicini allo zero e crea nuove istanze per valori più grandi. Le ottimizzazioni possono ancora essere eseguite, ma l'assegnazione di una nuova istanza richiederà sempre un po 'di tempo.


In risposta ai commenti, mi permetta di concentrarsi su ciò che ho preso per essere il punto chiave della questione:

da quando abbiamo a che fare con un valore letterale, è possibile per il compilatore per sostituire il letterale primitivo con una scatola letterale

Sì, è possibile , ma non, il compilatore Oracle javac non fa t il suo.

Ha importanza? No, il risultato in termini di prestazioni per il pugilato su Boolean è infinitesimale; boxing boolean utilizzando la stessa tecnica valueOf() come altri primitivi è una scelta sicura e sana per il compilatore.

+0

Sarei sorpreso se la JIT non fosse in grado di farlo in linea e di rendere entrambe le opzioni sostanzialmente equivalenti.La prima frase è forse troppo categorica .. – assylias

+0

@assylias Sarei sorpreso anche io, ma succederebbe alla prima esecuzione? Anche se fosse così, il processo di ottimizzazione richiederebbe più tempo rispetto al codice che utilizzava 'Boolean.TRUE' invece di' true'? – erickson

+3

Penso che il punto chiave sia che il colpo di prestazioni principale si presenta ogni volta che un * nuovo oggetto * deve essere allocato. Nel caso di Boolean.valueOf(), un nuovo oggetto non viene mai assegnato. Il codice dovrebbe in realtà utilizzare la costante di classe Boolean.TRUE, anziché il letterale primitivo booleano, ma mi aspetterei che la differenza di prestazioni effettiva tra i due in questo caso sia infinitamente piccola, – scottb

Problemi correlati