2016-02-15 11 views
8

Ich habe eine Thread-Executor-Implementierung, wo die Kosten für einen Wrapper als sehr teuer angezeigt werden. Es gibt eine Wrapper-Klasse Aufgabe, die wie folgt definiert ist:Warum ist der Java-Methodenaufruf hier so teuer?

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

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

List<task> taskList; 

Für Fall im Anschluss an die Laufzeit ist ~ 800ms.

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

Während für den folgenden Fall ist ~ 7000ms.

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

Es passiert nicht isoliert, aber geschieht innerhalb des Codes des Executors. Ich frage mich nur, ob jemand einen Hinweis darauf hat, was passieren könnte?

Der runnable folgend für diesen Testfall übergeben wird:

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;                  
    } 

Als Referenz kann der Code auf github.com/sharvanath/TempThreadPool finden. Führen Sie den ThreadPoolTest aus, um das Ergebnis der Ausführung abzurufen. Versuchen Sie nun Zeile 41 von ThreadPool.java zu ändern und sehen Sie sich die Magie an.

+0

Was macht 'run'? Ist es ein No-Op? – 5gon12eder

+1

Es sollte (fast Null) Unterschied für den Code geben, den Sie hier gepostet haben. Es muss etwas in anderem Code sein. –

+5

Sie sollten nicht den gesamten Code teilen - Sie sollten ein * minimum * Beispiel einschließen, das das Problem demonstriert. –

Antwort

1

Bitte beachten Sie, dass Sie in java einige Tricks anwenden müssen, weil jvm den Code beim Fliegen mit JIT-Compiler optimieren kann und eine Menge Tricks ausführt, die Sie nicht kennen und die wie Ihre Tests aussehen macht nicht alle notwendigen Dinge, damit JVM diesen Job für Sie erledigt (Sie müssen sich vor dem Test aufwärmen, in Verkleidungen entkommen, toten Code und so weiter.)

Es ist ein guter Anfangspunkt zu lesen Dieses Thema - How do I write a correct micro-benchmark in Java?

Auch ich rate Ihnen, JMH-Framework für Ihre diese Art von Tests zu verwenden, die bereits viele Beispiele für ihre Verwendung in ihrem Quellcode haben.

+0

Sie geben einen Link an, bitte kopieren Sie die relevanten Teile, da Links kaputt gehen können. –