-1

Which one is faster, Foo.b or 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;
    }
}

Disassembled byte codes:

  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                                                                                                                                                                                      
}                                                                                                                                                                                                      

It seems that Foo.c() has an extra getfield, but Foo.b() also has extra operations.

SOFe
  • 7,867
  • 4
  • 33
  • 61
  • 3
    Maybe if you run it for a whole year eventually you will find out the difference ;D – Alexander Petrov Jul 07 '16 at 16:37
  • 2
    The most readable is certainly the second one. That's why you should use that one. – JB Nizet Jul 07 '16 at 16:58
  • 2
    After JIT has done whatever it does, there is likely no difference at all. – Andreas Jul 07 '16 at 17:36
  • 1
    I wonder why this question is downvoted? Although this question involves premature optimization, it still has its theoretical/academic significance. Although not useful to most "guys who writ teh codez", the question itself serves its unique purpose. – SOFe Jul 08 '16 at 11:39

2 Answers2

1

The differences on the bytecode level are in the 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"

The amount of operations executed is still the same, no matter which branch is taken so the only difference is some "wasted" bytecodes. In a real world situation this is not a performance issue, but rather a code style issue.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
0

Unless you are calling this code in a loop iterating millions of times, then the difference between the two approaches is only academic, and is highly unlikely to impact the overall performance of your system compared with operations that are significantly more costly, like disk or network i/o.

Kevin Hooke
  • 2,583
  • 2
  • 19
  • 33
  • I just realized that the nature of caching values is that the if-block is not going to run after the first time, and the only difference is in the if-block. I mistakenly thought that it also affected the calls after that. Still wouldn't have any **academic** difference in performance for subsequent calls, right? – SOFe Jul 08 '16 at 11:38
  • And yes, I know that the difference is very negligible (premature optimization). I asked this just because my OCD struggles whether to add `return` every time, and I found that there are no _academic_ answers to this question right now. – SOFe Jul 08 '16 at 11:38