2010-10-13 16 views
31

Ho cercato di capire che cosa significa veramente:Qual è il metodo di inlining?

funzione inline

In C++, una funzione membro definita nel dichiarazione della classe. (2) Una funzione chiama che il compilatore sostituisce con il codice effettivo per la funzione. La parola chiave inline può essere utilizzata per suggerire a il compilatore per eseguire l'espansione in linea del corpo di un membro o la funzione non membro di .

linea

Per sostituire una chiamata di funzione con una copia del codice della funzione durante compilazione.

Per esempio è scritto qualcosa come:

Quando un metodo è definitiva, può essere inline.

Qui: http://www.roseindia.net/javatutorials/final_methods.shtml

Mi può fare un esempio, o qualcosa o fondamentalmente mi aiuta a capire che cosa "esso può essere inline" si intende.

Grazie.

+1

Questo sarà di aiuto: http://java.sun.com/developer/onlineTraining/Programming/JDCBook/perf2.html#vm – codaddict

risposta

49

Inlining è un'ottimizzazione eseguita dal compilatore Java Just-In-Time.

Se si dispone di un metodo:

public int addPlusOne(int a, int b) { 
    return a + b + 1; 
} 

che si chiama in questo modo:

public void testAddPlusOne() { 
    int v1 = addPlusOne(2, 5); 
    int v2 = addPlusOne(7, 13); 

    // do something with v1, v2 
} 

il compilatore può decidere di sostituire la chiamata di funzione con il corpo della funzione, quindi il risultato sarebbe assomigliare in questo modo:

public void testAddPlusOne() { 
    int v1 = 2 + 5 + 1; 
    int v2 = 7 + 13 + 1 

    // do something with v1, v2 
} 

Il compilatore fa questo per salvare il sovraccarico o f effettivamente facendo una chiamata di funzione, il che implicherebbe spingere ogni parametro nello stack.

Questo può chiaramente essere fatto solo per le funzioni non virtuali. Considera cosa succederebbe se il metodo fosse sovrascritto in una sottoclasse e il tipo dell'oggetto contenente il metodo non fosse noto fino al runtime ... come sarebbe il compilatore a sapere quale codice copiare: il corpo del metodo della classe base o della sottoclasse metodo del corpo? Poiché tutti i metodi sono virtuali per impostazione predefinita in Java, è possibile contrassegnare esplicitamente quelli che non possono essere sostituiti come final (o inserirli in una classe final). Ciò aiuterà il compilatore a capire che il metodo non sarà mai sovrascritto, ed è sicuro inserirlo in linea. (Si noti che talvolta il compilatore può effettuare questa determinazione anche per i metodi non definitivi.)

Inoltre, la parola può essere nella citazione. Non è garantito che i metodi finali siano integri. Esistono vari modi per garantire che un metodo non sia in grado di essere sottolineato, ma non è possibile forzare il compilatore in linea. Quasi sempre lo saprà meglio di te quando l'inline aiuterà a ridurre la velocità del codice risultante.

Vedere wikipedia per una buona panoramica di vantaggi e problemi.

+10

Buona risposta, ma come nota: se si dispone di un metodo non finale che * non * sovrascrive, un buon JIT può capirlo e inserirlo comunque. Se poi carichi una classe che la sovrascrive, può annullare la funzione di inlining. – naiad

+0

Buon punto, l'ho aggiunto al corpo della risposta. –

+0

È molto esplicativo, grazie per questa grande risposta. – Tarik

9

Diciamo che dispone di una classe che assomiglia a questo:

public class Demo { 
    public void method() { 
     // call printMessage 
     printMessage(); 
    } 

    public void printMessage() { 
     System.out.println("Hello World"); 
    } 
} 

La chiamata a printMessage potrebbe essere "inline" nel seguente modo:

public class Demo { 
    public void method() { 
     // call printMessage 
     System.out.println("Hello World"); // <-- inlined 
    } 

    public void printMessage() { 
     System.out.println("Hello World"); 
    } 
} 

(Questo non è in realtà fatto su il livello di Java (nemmeno in livello bytecode) ma durante la compilazione JIT, ma l'esempio sopra illustra il concetto di inlining.)

Considerare ora cosa succederebbe se il metodo printMessage stato sovraccaricato da un'altra classe, in questo modo:

class SubDemo extends Demo { 
    public void printMessage() { 
     System.out.println("Something else"); 
    } 
} 

Ora, se il compilatore inline la chiamata a Demo.printMessage sarebbe bloccato con System.out.println("Hello World"); che sarebbe sbagliato nel caso in cui l'oggetto era in realtà un istanza di SubDemo.

Tuttavia, se il metodo è stato dichiarato final, ciò non dovrebbe in nessun caso essere il caso. Se il metodo è "finale", significa che non può mai essere sostituito con una nuova definizione, quindi è sicuro inserirlo in linea!

+0

Anche una buona risposta, ma come nota copiata da un'altra risposta: Se si dispone di un metodo non-finale che non si ignora, un buon JIT può capirlo e inserirlo comunque. Se poi carichi una classe che la sovrascrive, può annullare la funzione di inlining. – naiad

+0

È molto esplicativo, grazie per questa grande risposta. – Tarik

10

La chiamata di una funzione non è gratuita. La macchina deve mantenere uno stack frame in modo che possa tornare alla sezione del codice chiamante quando la funzione chiamata è completa. Mantenere lo stack (inclusi i parametri di funzione di passaggio su questo stack) richiede tempo.

Quando una funzione è allineata, il compilatore sostituisce la chiamata alla funzione con il codice della funzione in modo che si possa evitare la penalizzazione delle prestazioni di una chiamata di funzione in fase di esecuzione. Questo è uno dei classici compromessi nella programmazione: il codice run-time diventa un po 'più grande (occupa più memoria), ma funziona un po' più velocemente.

+0

Grazie. Al primo paragrafo, hai davvero ragione. – Tarik

Problemi correlati