2016-02-15 18 views
8

Mam implementację executora wątków, w której koszt opakowania jest bardzo kosztowny. Istnieje zadanie klasy opakowującej, które jest zdefiniowane w następujący sposób:Dlaczego wywołanie metody Java jest tak kosztowne?

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

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

List<task> taskList; 

W następującym przypadku czas działania wynosi ~ 800ms.

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

Dla następującego przypadku jest to ~ 7000ms.

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

Nie dzieje się to w izolacji, ale dzieje się wewnątrz kodu executora. Zastanawiasz się, czy ktoś ma podpowiedź, co się dzieje?

uruchamialny przepuszcza się następująco tego testu:

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

Dla porównania, kod znajduje się na github.com/sharvanath/TempThreadPool. Uruchom test ThreadPoolTest, aby uzyskać wynik wykonania. Teraz spróbuj zmienić linię 41 ThreadPool.java i zobacz magię.

+0

Co robi 'run'? Czy to nie jest operacja? – 5gon12eder

+1

Powinna istnieć (prawie zerowa) różnica dla kodu, który tu zamieściłeś. Musi być coś w innym kodzie. –

+5

Nie należy udostępniać całego kodu - należy dołączyć * minimalny * przykład demonstrujący problem. –

Odpowiedz

1

Proszę wziąć pod uwagę, że przy mikromanaging w java musisz użyć kilku lew, ponieważ jvm może zoptymalizować kod w locie z kompilatorem JIT i zrobić wiele sztuczek, o których nie wiesz, i wygląda na to, że twoje testy faktycznie nie wykonuje wszystkich wymaganych czynności, aby JVM mógł wykonać tę pracę za ciebie (musisz rozgrzać się przed testem, uciec w podszewkach, martwym kodzie i tak dalej.)

Warto zacząć od przeczytania ten temat - How do I write a correct micro-benchmark in Java?

Polecam także do korzystania z frameworku JMH dla tego rodzaju testów, które już mają wiele przykładów użycia w swoim kodzie źródłowym.

+0

Jeśli Podaj link, proszę skopiować na odpowiednie części, ponieważ linki mogą się zepsuć. –

Powiązane problemy