缓存的getter性能

时间:2016-07-07 16:35:58

标签: java performance

哪一个更快,Foo.b还是Foo.c?

public class Foo{
    int a = 0;
    public int b(){
        if(a == 0){
            return a = 1;
        }
        return a;
    }
    public int c(){
        if(a == 0){
            a = 1;
        }
        return a;
    }
}

反汇编的字节代码:

  public int b();                                                                                                                                                                                      
    Code:                                                                                                                                                                                              
       0: aload_0                                                                                                                                                                                      
       1: getfield      #2                  // Field a:I                                                                                                                                               
       4: ifne          14                                                                                                                                                                             
       7: aload_0                                                                                                                                                                                      
       8: iconst_1                                                                                                                                                                                     
       9: dup_x1                                                                                                                                                                                       
      10: putfield      #2                  // Field a:I                                                                                                                                               
      13: ireturn                                                                                                                                                                                      
      14: aload_0                                                                                                                                                                                      
      15: getfield      #2                  // Field a:I                                                                                                                                               
      18: ireturn                                                                                                                                                                                      

  public int c();                                                                                                                                                                                      
    Code:                                                                                                                                                                                              
       0: aload_0                                                                                                                                                                                      
       1: getfield      #2                  // Field a:I                                                                                                                                               
       4: ifne          12                                                                                                                                                                             
       7: aload_0                                                                                                                                                                                      
       8: iconst_1                                                                                                                                                                                     
       9: putfield      #2                  // Field a:I                                                                                                                                               
      12: aload_0                                                                                                                                                                                      
      13: getfield      #2                  // Field a:I                                                                                                                                               
      16: ireturn                                                                                                                                                                                      
}                                                                                                                                                                                                      

似乎Foo.c()有一个额外的getfield,但是Foo.b()也有额外的操作。

2 个答案:

答案 0 :(得分:1)

字节码级别的差异在if-block

7: aload_0         "Start of if {" 
8: iconst_1           
9: dup_x1             
10: putfield      #2
13: ireturn       "End of if } and method execution"      

7: aload_0         "Start of if {"
8: iconst_1        
9: putfield      #2"End of if }, but not end of execution"

执行的操作量仍然相同,无论采用哪个分支,唯一的区别是一些“浪费”的字节码。在现实世界中,这不是性能问题,而是代码样式问题。

答案 1 :(得分:0)

除非您在循环中调用此代码数百万次,否则这两种方法之间的差异只是学术性的,与极其昂贵的运算相比,极不可能影响系统的整体性能,例如磁盘或网络i / o。