Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the Java method call being so costly here? [closed]

Tags:

java

I have a thread executor implementation where the cost of a wrapper is showing up as very costly. There is a wrapper class Task which is defined as follows:

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

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

 List<task> taskList;

For following case the run time is ~800ms.

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

While for the following case it is ~7000ms.

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

It does not happen in isolation, but is happening inside the code of the executor. Just wondering if someone has a hint as to what might be going on?

The runnable being passed is the following for this test case:

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

For reference, the code can be found on github.com/sharvanath/TempThreadPool. Run the ThreadPoolTest for getting the result of the execution. Now try changing line 41 of ThreadPool.java and see the magic.

like image 208
Sharvanath Avatar asked Feb 15 '16 09:02

Sharvanath


1 Answers

Please take into account that doing micromanaging in java you have to use some tricks, because jvm can optimize code on fly with JIT compiler and do a lot of tricks that you don't know about, and looks like your tests actually doesn't do all required things to let JVM do this job for you.(you have to do warm up before test, escape in linings, dead code and so on.)

Its a good point to start is to read this topic - How do I write a correct micro-benchmark in Java?

Also I advice you to use JMH framework for your this kind of tests, that already have lot of examples of it's usage in its source code.

like image 88
TheHckblues Avatar answered Nov 15 '22 01:11

TheHckblues