53

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

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
asela38
  • 4,546
  • 6
  • 25
  • 31
  • 4
    polygene's answer is the one you should listen to. but if you are really think the difference matters, run each version a billion times or so, and see if there is any measurable difference. then come back and tells us about it . – Peter Recore Mar 08 '10 at 00:23
  • Why does it matter, is your program only 3 lines long that it matters so much how fast or slow that one lonely if statement runs ? – mP. Mar 08 '10 at 00:50
  • 7
    While we're on the subject, I'd like to prove that putting the opening curly brace on the same line as the conditional is more performant than other brace styles. – Ben Zotto Mar 08 '10 at 00:52
  • 18
    I will say that OP needs to be praised for effort, for digging into bytecodes, etc. With proper direction, this kind of determination will do well for OP. – polygenelubricants Mar 08 '10 at 01:02

16 Answers16

82

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
  • 376,812
  • 128
  • 561
  • 623
  • 7
    +1 for distinguishing between bytecode and assembly - this is a very important distinction to note. – Cam Mar 08 '10 at 00:35
  • 5
    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 Mar 08 '10 at 02:04
  • 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 Mar 08 '10 at 03:32
  • 29
    @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 Mar 08 '10 at 16:42
  • Ugh. Add another item to the "evidence I have ADHD" list. – Nicolás Mar 24 '10 at 04:12
  • 1
    The very fact that still after so many years people are missing the bigger picture many times is so demoralizing... Very appropriately answered and is relevant even till now – Soumen Mukherjee Oct 28 '19 at 08:31
23

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
  • 14,930
  • 16
  • 77
  • 128
  • I agree with what you say about readability. null is constant, and for comparisons that include constants `variable constant` is most readable. – Ponkadoodle Mar 08 '10 at 00:28
12

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.

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407
7

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
  • 14,999
  • 2
  • 48
  • 58
  • 17
    To each their own intuition... (Although you are definitely wrong about this. ;) ) – Ben Zotto Mar 08 '10 at 00:54
  • 6
    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. – user207421 Mar 08 '10 at 03:47
  • 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 Mar 08 '10 at 16:59
3

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

Matthew H
  • 5,831
  • 8
  • 47
  • 82
2

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

Michael D. Irizarry
  • 6,186
  • 5
  • 30
  • 35
2

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!

Humphrey Bogart
  • 7,423
  • 14
  • 52
  • 59
2

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.

acarlstein
  • 1,799
  • 2
  • 13
  • 21
  • 2
    This has already been debated, see [comments on another answer](http://stackoverflow.com/a/2398688/224132). You should edit this answer to explain why you think this is useful, even though those commenters say it isn't. – Peter Cordes Nov 30 '16 at 15:30
1

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
  • 90,123
  • 14
  • 117
  • 115
1

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
  • 9,878
  • 23
  • 75
  • 91
1

You can ignore this very minute optimisation stuff during coding

gmhk
  • 15,598
  • 27
  • 89
  • 112
1

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
  • 1,327
  • 4
  • 16
  • 33
0

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

Nuno André
  • 4,739
  • 1
  • 33
  • 46
Anton Balaniuc
  • 10,889
  • 1
  • 35
  • 53
0

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

    });

}

}

0

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

Bhaumik Thakkar
  • 580
  • 1
  • 9
  • 28
-3

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

tactoth
  • 897
  • 1
  • 12
  • 24