RFR (S) 8073479: Replace obj.getClass hacks with Objects.requireNonNull

Aleksey Shipilev aleksey.shipilev at oracle.com
Thu Feb 19 18:26:36 UTC 2015


On 02/19/2015 06:17 PM, Peter Levart wrote:
> On 02/19/2015 04:02 PM, Aleksey Shipilev wrote:
>>> >Hi Aleksey,
>>> >
>>> >Is profile pollution problem already fixed? Can Objects.requireNonNull
>>> >be used in performance critical code without fear of performance
>>> >regression?
>> What profile pollution? Objects.requireNonNull is a static method. See
>> also the link in bug description:
>>    http://cr.openjdk.java.net/~shade/scratch/NullChecks.java
>>
>> -Aleksey.
>>
> 
> Remi described it here:
> 
> http://mail.openjdk.java.net/pipermail/core-libs-dev/2014-April/026669.html

Okay, Remi's premise is that implicit null check is much cheaper than an
explicit one when it's not tripped. It's then seem to extend to mean
that pessimistically inflating the nullcheck into the explicit one costs
performance, and therefore one should avoid requireNonNull.

But then we all got confused with benchmarks and whatnot. The benchmark
from JDK-8047127 actually measures the cost of raising the exceptions,
where getClass and friends are profoundly cheating:
  https://bugs.openjdk.java.net/browse/JDK-8042127#comment-13611255
  http://cr.openjdk.java.net/~shade/8042127/NullCheckMix.java

However, if you do the actual benchmark that compares explicit NP checks
vs implicit NP checks (that benchmark is very tricky to get right):
 http://cr.openjdk.java.net/~shade/scratch/NullCheckPollution.java

Benchmark         (count)  (pollute)  Mode  Cnt  Score   Error  Units
NCP.testExplicit   100000      false  avgt   50  1.813 ± 0.004  ns/op
NCP.testExplicit   100000       true  avgt   50  1.891 ± 0.029  ns/op
NCP.testImplicit   100000      false  avgt   50  1.812 ± 0.003  ns/op
NCP.testImplicit   100000       true  avgt   50  1.811 ± 0.001  ns/op

There, testExplicit with pollution is the only one that has explicit
test+branch. The difference is minuscule (< 1/3 of CPU cycle), and I
would choose not to care, even for JDK code.

That test is crafted specifically so that compiler could not
disambiguate different callers. In real life, a Sufficiently Smart
Compiler may inline the callees and reprofile in the context of caller.
But even in the absence of that, the performance hit would be buried in
everything else.

In the places where you *need* the every last bit of performance, you
can do the by-hand explicit nullcheck. (Note that it is not a good idea
to do getClass anyway, because of JDK-8073432).

Thanks,
-Aleksey.




More information about the core-libs-dev mailing list