Above answers don't actually answer your question. So here is my:
In case performance is really matters for you - removing null
checks may be a good idea. Many high-performance libraries use this approach, for example, here is code of FastList class from HikariCP (fastest java DB connection pool):
public boolean add(T element)
{
try {
elementData[size++] = element;
} catch (ArrayIndexOutOfBoundsException e) {
...
}
}
This try catch was added as replacement of range check. Removal of bounds-checks actually makes this code faster.
Here is the benchmark that proves that:
@BenchmarkMode(Mode.Throughput)
@Fork(1)
@State(Scope.Thread)
@Warmup(iterations = 10, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1000)
@Measurement(iterations = 20, time = 1, timeUnit = TimeUnit.SECONDS, batchSize = 1000)
public class BoundsCheck {
@Param("1")
int index;
int[] ar;
@Setup
public void setup() {
ar = new int[] {1, 2};
}
@Benchmark
public int boundCheck() {
if (index >= ar.length) {
throw new IndexOutOfBoundsException();
}
return ar[index];
}
@Benchmark
public int noCheck() {
return ar[index];
}
@Benchmark
public int noCheckWithTryCatch() {
try {
return ar[index];
} catch (RuntimeException e) {
return -1;
}
}
}
Result:
Benchmark (index) Mode Cnt Score Error Units
BoundsCheck.boundCheck 1 thrpt 20 334197.761 ± 2593.034 ops/s
BoundsCheck.noCheck 1 thrpt 20 370148.527 ± 9016.179 ops/s
BoundsCheck.noCheckWithTryCatch 1 thrpt 20 371782.744 ± 17290.347 ops/s
What can we see here? Eliminating of bound-check gives you +10% performance gain. try {} catch
costs nothing until exception is thrown.
However, this approach is suitable only in situations when you can guarantee that you'll have no NPE's in your data. So exceptions actually will never be thrown or thrown very rarely. Otherwise, exception throwing may make your code even slower.
Here is no precise answer. This really depends on your data and you need to know your data in order to make any further conclusions.
Also, have in mind that JIT can take care of eliminating null
's checks in your code when it can, so this optimization may not worth it. Only tests with real data could give you an answer.