1

I was wondering if there was any significative difference on checking if an object is null in java with direct comparison, or by using the Objects.isNull() method.

public class Test {

  public final static Long ITERATIONS = 100000000L; 

  @Test
  public void noFnCalls() {
    balong startTime = System.currentTimeMillis();
    Object x = new Object();
    Long i;
    for (i = 0L; i < ITERATIONS; i++) {
      boolean t = x == null;
    }
    long estimatedTime = System.currentTimeMillis() - startTime;
    System.out.println("noFnCalls ellapsed time: " + estimatedTime);
  }

  @Test
  public void withFnCalls() {
    long startTime = System.currentTimeMillis();
    Object x = new Object();
    Long i;
    for (i = 0L; i < ITERATIONS; i++) {
      boolean t = Objects.isNull(x);
    }
    long estimatedTime = System.currentTimeMillis() - startTime;
    System.out.println("withFnCalls ellapsed time: " + estimatedTime);
  }
}

And surprisingly, at least for me, it always takes more time to finish the "noFnCalls". I was expecting pretty much the opposite result, since it results into a method call, using stack.

This is the output: (Changes every time, obviously, but always with "noFnCalls" higher)

noFnCalls ellapsed time: 583

withFnCalls ellapsed time: 463

Why is this produced?

4
  • 7
    Writing a correct microbenchmark in Java is tricky. Have you warmed up your system? Are your results the same if you run the tests in the reverse order? Commented Jun 8, 2018 at 7:02
  • 3
    Please see: stackoverflow.com/questions/504103/… Commented Jun 8, 2018 at 7:05
  • Practically, it doesnt matter which of the two you use, since the performence gain is minimal. However, Objects#isNull is meant to be used as a predicate. Commented Jun 8, 2018 at 8:02
  • This test is invalid, t is unused and constant. Commented Jun 8, 2018 at 11:30

1 Answer 1

5

The results you see are probably due to running "noFnCalls" first, without introducing proper warmup before the test and the measurement.

I get this:

withFnCalls ellapsed time: 444
noFnCalls ellapsed time: 471
withFnCalls ellapsed time: 334
noFnCalls ellapsed time: 331
withFnCalls ellapsed time: 330
noFnCalls ellapsed time: 325
withFnCalls ellapsed time: 331
noFnCalls ellapsed time: 326
withFnCalls ellapsed time: 326
noFnCalls ellapsed time: 328

Using

import java.util.Objects;

public class Test {

  public final static Long ITERATIONS = 100000000L; 

  public static void main(String args[]) {
    withFnCalls();
    noFnCalls();
    withFnCalls();
    noFnCalls();
    withFnCalls();
    noFnCalls();
    withFnCalls();
    noFnCalls();
    withFnCalls();
    noFnCalls();
  }
  public static void noFnCalls() {
    long startTime = System.currentTimeMillis();
    Object x = new Object();
    Long i;
    for (i = 0L; i < ITERATIONS; i++) {
      boolean t = x == null;
    }
    long estimatedTime = System.currentTimeMillis() - startTime;
    System.out.println("noFnCalls ellapsed time: " + estimatedTime);
  }

  public static void withFnCalls() {
    long startTime = System.currentTimeMillis();
    Object x = new Object();
    Long i;
    for (i = 0L; i < ITERATIONS; i++) {
      boolean t = Objects.isNull(x);
    }
    long estimatedTime = System.currentTimeMillis() - startTime;
    System.out.println("withFnCalls ellapsed time: " + estimatedTime);
  }
}

and

withFnCalls ellapsed time: 3618
noFnCalls ellapsed time: 3361
withFnCalls ellapsed time: 3445
noFnCalls ellapsed time: 3278
withFnCalls ellapsed time: 3350
noFnCalls ellapsed time: 3292
withFnCalls ellapsed time: 3309
noFnCalls ellapsed time: 3262
withFnCalls ellapsed time: 3293
noFnCalls ellapsed time: 3261

If I increase to 1000000000L iterations. This was done with Java 9 64-bit server jvm, build 9+181, by Oracle, running on Windows 10 with a machine having Intel i5-2600 cpu.

Like others have said, micro-benchmarking is hard and lot of different things affect the results. You shouldn't jump on conclusions with tests like these. This kind of test does not really tell much - any differences get easily lost in the noise measuring code that are so close to each other.

Obligatory recommended thread about micro-benchmarking in java: How do I write a correct micro-benchmark in Java?.

Sign up to request clarification or add additional context in comments.

1 Comment

Same result also with Java 1.8.0 x64 on Windows 10, Linux/Debian and FreeBSD.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.