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

Peter Levart peter.levart at gmail.com
Fri Feb 20 12:48:07 UTC 2015


On 02/19/2015 07:26 PM, Aleksey Shipilev wrote:
> 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.

Hi Aleksey,

Good to know that requireNonNull is mostly not an issue after all. 
Thanks for taking time to create a real microbenchmark for it. I too 
have tried, but couldn't get it to show any difference between polluted 
and non-polluted test case (probably because I didn't use 
CompilerControl.Mode.DONT_INLINE ). Running your test on my hw (i7-2600K 
CPU) gives a little different result though (this is with 64bit JDK 8u20):


Benchmark                              (count)  (pollute)  Mode 
Samples   Score   Error  Units
j.t.NullCheckPollution.testExplicit     100000      false avgt       
50   1.908 ± 0.052  ns/op
j.t.NullCheckPollution.testExplicit     100000       true avgt       
50   2.291 ± 0.036  ns/op
j.t.NullCheckPollution.testImplicit     100000      false avgt       
50   1.906 ± 0.048  ns/op
j.t.NullCheckPollution.testImplicit     100000       true avgt       
50   1.865 ± 0.025  ns/op


...and with recent build of JDK9:


Benchmark                              (count)  (pollute)  Mode Samples  
Score   Error  Units
j.t.NullCheckPollution.testExplicit     100000      false avgt       50  
1.871 ± 0.056  ns/op
j.t.NullCheckPollution.testExplicit     100000       true avgt       50  
2.278 ± 0.022  ns/op
j.t.NullCheckPollution.testImplicit     100000      false avgt       50  
1.867 ± 0.025  ns/op
j.t.NullCheckPollution.testImplicit     100000       true avgt       50  
1.899 ± 0.058  ns/op


Perhaps my CPU is too old (4 years!) to be smart enough (like yours)? I 
checked on a Sparc-T5 CPU (JDK 8u40b23) too:


Benchmark                              (count)  (pollute)  Mode Samples  
Score   Error  Units
j.t.NullCheckPollution.testExplicit     100000      false avgt       50  
3.089 ± 0.062  ns/op
j.t.NullCheckPollution.testExplicit     100000       true avgt       50  
3.596 ± 0.090  ns/op
j.t.NullCheckPollution.testImplicit     100000      false avgt       50  
3.100 ± 0.060  ns/op
j.t.NullCheckPollution.testImplicit     100000       true avgt       50  
3.211 ± 0.204  ns/op


...but this only happens if the method doing explicit null check is not 
inlined into the test method. If I change DONT_INLINE -> INLINE, the 
difference is hidden within noise (i7-2600K, JDK9):


Benchmark                              (count)  (pollute)  Mode Samples  
Score   Error  Units
j.t.NullCheckPollution.testExplicit     100000      false avgt       50  
0.456 ± 0.005  ns/op
j.t.NullCheckPollution.testExplicit     100000       true avgt       50  
0.482 ± 0.024  ns/op
j.t.NullCheckPollution.testImplicit     100000      false avgt       50  
0.457 ± 0.006  ns/op
j.t.NullCheckPollution.testImplicit     100000       true avgt       50  
0.456 ± 0.004  ns/op


So we hope for Objects.requireNonNull to be inlined most of the times. 
It would be nice if @ForceInline annotation was accessible outside 
java.lang.invoke package, so methods like requireNonNull could benefit 
from it too. With modules, such platform annotations could be made 
public and put into a package (java.lang.internal) that is not exported 
to the world.


Regards, Peter






More information about the core-libs-dev mailing list