2011-09-17 15 views
5

Ero curioso, vedo questo genere di cose molto:Il compilatore JDK ottimizza l'uso di classi anonime senza variabili di istanza?

Arrays.sort(array, new Comparator<Integer>() { 
    public int compare(Integer a, Integer b) { 
     return Math.abs(a) < Math.abs(b); 
    } 
}); 

dal momento che la classe anonima creato qui non ci sono le variabili di istanza, è il compilatore standard JDK abbastanza intelligente da solo istanziare quella classe anonima, una volta e riutilizzarlo ? O è consigliabile istanziare quella classe anonima in un campo statico e passare sempre l'oggetto Comparator statico?

UPDATE: Quando dico "compilatore JDK", intendo la parte JIT troppo. Quanto sopra è anche solo un esempio. Ero davvero curioso se dovessi, come best practice, creare campi statici per quanto sopra invece di allineare istanze di classi anonime. In alcuni casi il problema dell'utilizzo delle risorse/prestazioni sarà trascurabile. Ma altri casi potrebbero non essere ...

risposta

3

javac sarà sicuramente non fare una cosa del genere; ciò violerebbe la semantica della lingua. JVM potrebbe ottimizzarlo in teoria, ma non è ancora così intelligente. Uno statico sarebbe più veloce.

Ironia della sorte, tale analisi e ottimizzazione sarebbe facile per javac, e può essere fatto oggi, tranne che è vietato farlo - la fonte dice new, quindi javac deve new.

Si dice che l'espressione lambda venire in Java 8 farà uno sforzo su questo tema, in

Arrays.sort(array, (Integer a,Integer b) => Math.abs(a)<Math.abs(b)) 

javac è necessario per analizzare che il lambda è senza stato, e una singola istanza pigramente creata è abbastanza , ed è quello che deve compilare il codice.

0

È possibile utilizzare javap per controllare se stessi; il mio sospetto è che lo creerà ad ogni chiamata. Tali ottimizzazioni sono gestite da hotspot ma in questo caso poiché l'anonimo ha solo metodi (nessun campo da inizializzare) il sovraccarico è molto piccolo.

1

La risposta è forse.

javac lo compila in un bytecode fedele al codice. Pertanto, la classe verrà istanziata nuovamente ogni volta che viene chiamato questo codice. Tuttavia, la JVM esegue molte ottimizzazioni sofisticate in fase di esecuzione e MIGHT, a seconda di molti fattori, esegue alcune ottimizzazioni qui.

In ogni caso, a meno che tu non abbia notato un problema di prestazioni reali qui, ti consiglio di non provare a ottimizzare manualmente.

0

La vera domanda qui non è quella che farà lo javac. Come dice Steve McLeod, javac produrrà un codice bytecode che corrisponde al codice sorgente. La domanda è cosa farà l'htpot in fase di runtime. Immagino che sarà semplice incorporare tutto (compresa la chiamata Math.abs()).

0

Il compilatore non ottimizza molto. Il jit fa quasi tutto. Ottimizzerà questo codice ma non eviterà di creare oggetti Integer e, a meno che tu non abbia un array di Integer, questo sarà il tuo collo di bottiglia. Tanto che qualsiasi altra ottimizzazione non ha importanza.

Problemi correlati