' ... != null' or 'null != ....' best performance?

JavaPerformanceMicro Optimization

Java Problem Overview


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 :) )

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

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.

Solution 3 - Java

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.)


Update: The code above runs an ad-hoc benchmark. Using JMH (now that it exists!) is a good way to help avoid (some) microbenchmarking pitfalls. The code above avoids the worst pitfalls but it doesn't give explicit error estimates and ignores various other things that sometimes matter. These days: use JMH! Also, when in doubt, run your own benchmarks. Details sometimes matter — not very often for something as straightforward as this, but if it is really important to you you should check in a condition as close to production as you can manage.

Solution 4 - Java

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.

Solution 5 - Java

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

Solution 6 - Java

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

Solution 7 - Java

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!

Solution 8 - Java

From the point of view, there is no significant difference in performance.

However, it is useful to write the null first to catch typos errors.

For example, if you are used to write this code:

if (obj == null)

Could be wrote by mistake as:

if (obj = null)

From the point of view of the compiler, this is fine.

However, If you are used to write the code as:

if (null == obj)

and made the mistake to write:

if (null = obj)

the compiler will let you know you made a mistake in that line.

Solution 9 - Java

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.

Solution 10 - Java

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.

Solution 11 - Java

You can ignore this very minute optimisation stuff during coding

Solution 12 - Java

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.

Solution 13 - Java

In Java-8 two additional methods were introduced to Objects class: Objects#nonNull and Objects#isNull, which you can use to replace null checks. An interesting things is that both of them use objects first:

public static boolean isNull(Object obj) {
    return obj == null;
}

and

public static boolean nonNull(Object obj) {
    return obj != null;
}

correspondingly. I guess it means that this is the recommended way (at least core jdk developers used that approach) Objects source code

Solution 14 - Java

I would use the "new" Java 8 feature, I write several examples:

import java.util.Optional;

public class SillyExample {

public void processWithValidation(final String sampleStringParameter){
    final String sampleString = Optional.ofNullable(sampleStringParameter).orElseThrow(() -> new IllegalArgumentException("String must not be null"));

    //Do what you want with sampleString
}


public void processIfPressent(final String sampleStringParameter){
    Optional.ofNullable(sampleStringParameter).ifPresent(sampleString -> {

        //Do what you want with sampleString
        
    });

}

public void processIfPressentWithFilter(final String sampleStringParameter){
    Optional.ofNullable(sampleStringParameter).filter("hello"::equalsIgnoreCase).ifPresent(sampleString -> {

        //Do what you want with sampleString

    });

}

}

Solution 15 - Java

I would prefer null != object as it makes clearly visible that it's just for null check.

Solution 16 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionasela38View Question on Stackoverflow
Solution 1 - JavapolygenelubricantsView Answer on Stackoverflow
Solution 2 - JavaCamView Answer on Stackoverflow
Solution 3 - JavaRex KerrView Answer on Stackoverflow
Solution 4 - JavasehView Answer on Stackoverflow
Solution 5 - JavaMatthew HView Answer on Stackoverflow
Solution 6 - JavaMichael D. IrizarryView Answer on Stackoverflow
Solution 7 - JavaHumphrey BogartView Answer on Stackoverflow
Solution 8 - JavaacarlsteinView Answer on Stackoverflow
Solution 9 - JavaAnthony ForloneyView Answer on Stackoverflow
Solution 10 - JavaMichael MaoView Answer on Stackoverflow
Solution 11 - JavagmhkView Answer on Stackoverflow
Solution 12 - JavaBipulView Answer on Stackoverflow
Solution 13 - JavaAnton BalaniucView Answer on Stackoverflow
Solution 14 - JavaMarco Tulio Avila CerónView Answer on Stackoverflow
Solution 15 - JavaBhaumik ThakkarView Answer on Stackoverflow
Solution 16 - JavatactothView Answer on Stackoverflow