views:

762

answers:

12

I wrote two methods to check there performance

 public class Test1 {

 private String value;

 public void notNull(){
  if( value != null) {
    //do something
  }
}

public void nullNot(){
 if( null != value) {
  //do something
 }
}

}

and checked it's byte code after compiling

public void notNull();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: getfield #2; //Field value:Ljava/lang/String;
4: ifnull 7
7: return
LineNumberTable: 
line 6: 0
line 9: 7

StackMapTable: number_of_entries = 1
frame_type = 7 /* same */


public void nullNot();
Code:
Stack=2, Locals=1, Args_size=1
0: aconst_null
1: aload_0
2: getfield #2; //Field value:Ljava/lang/String;
5: if_acmpeq 8
8: return
LineNumberTable: 
line 12: 0
line 15: 8

StackMapTable: number_of_entries = 1
frame_type = 8 /* same */


}

in here two opcodes are used to implement the if condition: in first case it use ifnull- check top value of stack is null-, and in second case it use if_acmpeq- check top two value are equal in the stack-

so, will this make an effect on performance? (this will helps me to prove first implementation of null is good in performance wise as well as in the aspect of readability :) )

+32  A: 

Comparing the generated bytecodes is mostly meaningless, since most of the optimization happens in run time with the JIT compiler. I'm going to guess that in this case, either expression is equally fast. If there's any difference, it's negligible.

This is not something that you need to worry about. Look for big picture optimizations.

polygenelubricants
+1 for distinguishing between bytecode and assembly - this is a very important distinction to note.
Cam
+1 for "look at the big picture"
Thilo
It's pretty simple really: if one was faster than the other, some smart guys at Microsoft would have *already* made the compiler or the JIT convert the slow one into the fast one.
Nicolás
Good point on bytecodes, but how do you know that this isn't a big picture optimization? If you're looking at sparsely-populated data, checking for null could be where your code spends most of its time.
Rex Kerr
@Nicolas, considering this is java, not c#, the guys at Microsoft probably would have made the compiler convert the fast one into the slow one :)
Peter Recore
Ugh. Add another item to the "evidence I have ADHD" list.
Nicolás
+1  A: 

Putting null first seems to generate an extra byte-code, but aside from that there may not be a performance difference.

Personally, I wouldn't worry about performance until its time to worry about performance.

I would use the notNull() approach, just so you don't throw a compiler error if you forget the ! and accidentally type null = value.

Anthony Forloney
but in the case in if condition if you do the same mistake, it won't compile, if not value is Boolean type
asela38
I think you're more likely to make a typo when typing `notNull(value)` than `value != null`.
Wallacoloo
Yeah agreed, I meant to speak in generality when performing a type check, I did not make that clear though. Thank you.
Anthony Forloney
+7  A: 

Don't optimize at the expense of readability if the speed (or memory/whatever the case may be) gain will be negligible. I think !=null is generally more readable, so use that.

Cam
I agree with what you say about readability. null is constant, and for comparisons that include constants `variable <comparison> constant` is most readable.
Wallacoloo
+2  A: 

The difference will be negligable so go with what's most readable (!= null imo)

Matt H
+1  A: 

Oh, if you ask for ultimate performance, don't create additional class or methods. Even static methods would take a bit of time as the Java class loader needs to JIT load it.

So, whenever you need to check if a variable is null, you just test it by either

if (x == null)

or

if (null == x)

Frankly I reckon the performance bonus to pick one of the two is easily offset by the overhead of introducing unnecessary methods.

Michael Mao
I'm sure these methods where only introduced as an easy way to see the difference in generated bytecode.
Christian Semrau
+1  A: 

I'd stick with (value != null) for readability. But you can always use Assertions.

JeremySpouken
+2  A: 

Apart from the hard-earned wisdom of avoiding accidental assignment in C, which favors putting the constant on the left of the binary operator, I find the constant on the left to be more readable because it puts the crucial value in the most prominent position.

Usually a function body will use only a few variables, and it's usually apparent by way of context which variable is under inspection. By putting the constant on the left, we more closely mimic switch and case: given this variable, select a matching value. Seeing the value on the left, one focuses on the particular condition being selected.

When I scan

if (var == null)

I read it as, "We're inspecting var here, and we're comparing it for equality, against ... ah, null." Conversely, when I scan

if (null == var)

I think, "We're seeing if a value is null, and ... yes, it's var we're inspecting." It's an even stronger recognition with

if (null != var)

which my eye just picks up on immediately.

This intuition comes from consistency of habit, preferring to read what one writes, and writing what one prefers to read. One can learn it either way, but it's not objectively true as others have answered here that putting the variable on the left is clearer. It depends on what aspect of the expression one wants to be most clear first.

Seeing the bytecode difference was fascinating. Thanks for sharing that.

seh
To each their own intuition... (Although you are definitely wrong about this. ;) )
quixoto
The 'hard earned wisdom of avoiding accidental assignment in C' is about 20 years out of date, since C compilers now produce warnings about that (rather than having to get them from 'lint'), and it doesn't actually apply to Java.
EJP
That compilers warn about this now doesn't change the reason why long-time programmers may have first adopted this style, but that doesn't matter. My point here is that avoiding such accidental assignment isn't the only benefit of the style, and there's still good reason to adopt it today. Depending on what the reader is most interested in, this style can "read better".
seh
+2  A: 

Minute optimization like that is the job of the compiler, especially in high-level languages like Java.

Although strictly it's not relevant here, don't optimize prematurely!

Beau Martínez
+1  A: 

With questions like this, it's hard to know how smart the JVM will be (though the answer is "usually pretty smart if possible" and it looks very possible in this case). But just to be sure, test it:

class Nullcheck {
  public static class Fooble { }

  Fooble[] foo = {null , new Fooble(), null , null,
                  new Fooble(), null, null, new Fooble() };

  public int testFirst() {
    int sum = 0;
    for (int i=0 ; i<1000000000 ; i++) if (foo[i&0x7] != null) sum++;
    return sum;
  }

  public int testSecond() {
    int sum = 0;
    for (int i=0 ; i<1000000000 ; i++) if (null != foo[i&0x7]) sum++;
    return sum;
  }

  public void run() {
    long t0 = System.nanoTime();
    int s1 = testFirst();
    long t1 = System.nanoTime();
    int s2 = testSecond();
    long t2 = System.nanoTime();
    System.out.printf("Difference=%d; %.3f vs. %.3f ns/loop (diff=%.3f)\n",
      s2-s1,(t1-t0)*1e-9,(t2-t1)*1e-9,(t0+t2-2*t1)*1e-9);
  }

  public static void main(String[] args) {
    Nullcheck me = new Nullcheck();
    for (int i=0 ; i<5 ; i++) me.run();
  }
}

And on my machine this yields:

Difference=0; 2.574 vs. 2.583 ns/loop (diff=0.008)
Difference=0; 2.574 vs. 2.573 ns/loop (diff=-0.001)
Difference=0; 1.584 vs. 1.582 ns/loop (diff=-0.003)
Difference=0; 1.582 vs. 1.584 ns/loop (diff=0.002)
Difference=0; 1.582 vs. 1.582 ns/loop (diff=0.000)

So the answer is: no, no meaningful difference at all. (And the JIT compiler can find extra tricks to speed each up after the same number of repeat runs.)

Rex Kerr
+1  A: 

You can ignore this very minute optimisation stuff during coding

harigm
+1  A: 

As you can see the performance different is very less. Don't worry about the small things it is always better to focus more on algorithm. And obviously readability is a factor.

Bipul
A: 

Byte code is just a simple translation of the source code.

tactoth
That depends entirely on which compiler you're using.
EJP