2016-02-15 14 views
8

Ho un'implementazione thread executor in cui il costo di un wrapper risulta molto costoso. Esiste una classe wrapper Task che è definita come segue:Perché la chiamata al metodo Java è così costosa qui?

class Task { 
    public Runnable r;  
    public Task(Runnable r) {   
    this.r = r;                 
    } 

    public void run() {  
    r.run();  
    }  

List<task> taskList; 

Per il seguente caso il tempo di esecuzione è ~ 800 ms.

for (Task t : taskList) {             
      t.r.run();     
    } 

Mentre per il seguente caso è ~ 7000 ms.

for (Task t : taskList) {   
      t.run();                
} 

Non succede in isolamento, ma sta accadendo all'interno del codice dell'esecutore. Mi chiedo solo se qualcuno ha un suggerimento su cosa potrebbe succedere?

L'eseguibile viene passato è la seguente per questo tipo di test:

class Tester implements Runnable {             
    int i;                   

    public Tester(int i) {               
    this.i = i;                  
    }                     

    @Override                   
    public void run() {                
    //System.out.println(i);              
    for (int j = 0; j < 1000000; j++) {            
     i = j;                  
    }                    
    }                     

    public int getI() {                
    return i;                  
    } 

Per riferimento, il codice può essere trovato sul github.com/sharvanath/TempThreadPool. Esegui ThreadPoolTest per ottenere il risultato dell'esecuzione. Ora prova a cambiare la linea 41 di ThreadPool.java e vedere la magia.

+0

Cosa fa "run' do? È un no-op? – 5gon12eder

+1

Ci dovrebbe essere (quasi zero) la differenza per il codice che hai postato qui. Ci deve essere qualcosa in un altro codice. –

+5

Non si deve condividere l'intero codice: è necessario includere un esempio * minimo * che mostri il problema. –

risposta

1

Si prega di prendere in considerazione che facendo micromanaging in java è necessario utilizzare alcuni trucchi, perché jvm può ottimizzare il codice al volo con il compilatore JIT e fare un sacco di trucchi che non si conoscono, e sembra proprio che i test in realtà non fa tutto ciò che è necessario per consentire a JVM di fare questo lavoro per te (devi riscaldarti prima di testare, scappare in fodere, codice morto e così via.)

È un buon punto di partenza da leggere questo argomento - How do I write a correct micro-benchmark in Java?

Inoltre, consiglio di utilizzare il framework JMH per questo tipo di test, che ha già molti esempi del suo utilizzo nel codice sorgente.

+0

Se si fornisce un collegamento, si prega di copiare le parti rilevanti in quanto i collegamenti possono rompersi. –

Problemi correlati