2015-12-24 23 views
11

Ho fatto un po 'di ricerche ma vedo soprattutto risposte C++. Il più vicino a cui sono arrivato è this. Ho visto anche this page ma in realtà non spiega nulla.Java: il codice inlining avrà dei vantaggi?

Ci sono dei vantaggi se utilizzo il secondo pezzo di codice? Ci saranno differenze di prestazioni notevoli? Che mi dici della memoria? Cosa succede se è fatto ripetutamente?

In questo momento ho questa funzione. Sono sicuro che il vantaggio di questo è la leggibilità del codice:

private static Bitmap resize(Bitmap image, int maxWidth) { 
    float widthReducePercentage = ((float) maxWidth/image.getWidth()); 
    int scaledHeight = Math.round(image.getHeight() * widthReducePercentage); 

    return Bitmap.createScaledBitmap(image, maxWidth, scaledHeight, true); 
} 

Ora, io ho questo secondo frammento di codice:

private static Bitmap resize(Bitmap image, int maxWidth) { 
    return Bitmap.createScaledBitmap(image, maxWidth, Math.round(image.getHeight() * (float) maxWidth/image.getWidth()), true); 
} 

Un esempio più semplice potrebbe essere:

for(;;) { 
    String foo = "hello"; 
    Console.print(foo + "world"); 
} 

contro

for(;;) { 
    Console.print("hello" + "world"); 
} 
+0

Credo che il compilatore ottimizzi comunque le cose, quindi gli esempi di coppie di test potrebbero funzionare allo stesso modo. In ogni caso, l'inlining può facilitare la lettura del codice. –

+2

Per gli esempi forniti non ci saranno differenze di prestazioni. Non preoccupatevi nemmeno delle "ottimizzazioni" come queste, basta fare ciò che si legge meglio. –

+0

@LouisWasserman Roger that – pandalion98

risposta

9

Primo: questo non è il significato di "inlining". Vedi: What is inlining?

Secondo: no, non ci sarà alcuna differenza misurabile nelle prestazioni. In entrambi gli esempi di codice, è probabile che il codice compilato sia identico per entrambe le versioni.

+2

Il bytecode Java sarà diverso, in quanto le variabili locali non vengono eliminate (sono disponibili per il debug). Il JIT e presumibilmente il compilatore di Dalvik li avrebbe rimossi. – chrylis

+0

Dopo aver postato questa risposta, ho fatto un semplice esperimento, simile a LIProf. E i file compilati erano davvero diversi. Tranne che ho usato il flag '-g: none', quindi non ci dovrebbero essere stati simboli di debugging. Quindi immagino sia un po 'più complicato di quanto pensassi. –

3

Sono entrambi i sam e. il primo rende solo le cose più chiare di quest'ultimo.

Ci sono situazioni come il blocco sottostante che rendono utili le one-liner.

public boolean isEmpty() { 
    return getCount() != 0; 
} 

Se si vuole rendere più facile da leggere, soprattutto quando si tratta di equazioni, andare a fare una variable. le one-liner lo rendono semplice e breve, ma fa bene a logiche brevi e semplici.

Questa è la mia opinione personale.

4

Ho definito due classi semplici Test1 e Test2 e le ho compilate.

public class Test1{ 
    public String f(){ 
     String s = "Hello"; 
     String t = "There"; 
     return s + t; 
    } 
} 

e

public class Test2{ 
    public String f(){ 
     return "Hello" + "There"; 
    } 
} 

Con mia grande sorpresa, i file .class non sono della stessa dimensione.

-rw-r--r-- 1 csckzp staff 426 Dec 23 19:43 Test1.class 
-rw-r--r-- 1 csckzp staff 268 Dec 23 19:43 Test2.class 

Forse non dovrebbe essere sorpreso, dal momento che una certa quantità di informazioni simbolica viene memorizzato insieme al codice. Ho eseguito i file .class tramite un decompilatore online. Test1 è stata ricostruita più o meno il modo in cui è stato digitato Test2, d'altra parte, decompilato in questo modo:.

public class Test2 { 
    public String f() { 
     return "HelloThere"; 
    } 
} 

ottimizzazione del compilatore mostra chiaramente qui. Forse c'è una piccola penalità in Java per il codice non compatto.

+1

Non sono sorpreso; il compilatore bytecode fa * molto * l'ottimizzazione minima. La loro equivalenza sarà dimostrata in fase di esecuzione. – Veedrac

+1

Il compilatore tenta di eliminare le operazioni il cui risultato può essere determinato in fase di compilazione. Ecco perché "Hello" + "There" è diventato "HelloThere". –

1

Mentre le variabili locali sopravvivono alla traduzione in bytecode, è molto improbabile che sopravvivano solo in tempo di compilazione.Inoltre, anche se fossero presenti le variabili locali, esse non influirebbero in modo significativo sulle prestazioni di tale metodo, in quanto la ridimensionamento di una bitmap è di ordini di grandezza più costosi rispetto all'archiviazione o al recupero di una variabile locale.

Il secondo esempio sulla concatenazione di stringhe evidenzia una piccola eccezione a questa regola, in quanto la presenza di variabili locali può inibire la valutazione del tempo di compilazione della concatenazione di stringhe costanti. Tuttavia, è improbabile che ciò possa influire in modo significativo sul runtime del programma, poiché probabilmente non si concatenano stringhe costanti molto spesso.

In generale, l'effetto dell'inallineamento delle variabili locali sulle prestazioni di runtime è molto raramente misurabile, per non dire significativo. Pertanto, è molto meglio spendere il tuo tempo ottimizzando le prestazioni del programmatore rendendo il tuo codice facile da leggere e ragionare.