为什么Java方法调用在这里如此昂贵?

Sha*_*ath 8 java

我有一个线程执行器实现,其中包装器的成本显示为非常昂贵.有一个包装类Task,定义如下:

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

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

 List<task> taskList;
Run Code Online (Sandbox Code Playgroud)

对于以下情况,运行时间约为800毫秒.

  for (Task t : taskList) {                                                 
           t.r.run();                 
    }
Run Code Online (Sandbox Code Playgroud)

而对于以下情况,它是~7000ms.

 for (Task t : taskList) {        
           t.run();                                                              
 }
Run Code Online (Sandbox Code Playgroud)

它不是孤立发生的,而是发生在执行者的代码中.只是想知道是否有人暗示可能会发生什么?

对于此测试用例,传递的runnable如下:

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;                                                                      
  }  
Run Code Online (Sandbox Code Playgroud)

作为参考,代码可以在github.com/sharvanath/TempThreadPool找到.运行ThreadPoolTest以获取执行结果.现在尝试更改ThreadPool.java的第41行并查看魔法.

小智 1

请考虑到,在java中进行微观管理时,您必须使用一些技巧,因为jvm可以使用JIT编译器动态优化代码,并执行许多您不知道的技巧,并且看起来您的测试实际上并没有这样做让 JVM 为您完成这项工作所需的所有事情。(您必须在测试前进行预热、衬里转义、死代码等等。)

阅读本主题是一个很好的起点 -如何在 Java 中编写正确的微基准?

另外,我建议您使用 JMH 框架进行此类测试,该框架的源代码中已经有很多使用示例。