RFR 8009736: Comparator API cleanup

John Rose john.r.rose at oracle.com
Tue Jun 18 16:40:02 PDT 2013

On Jun 18, 2013, at 3:38 PM, Tom Hawtin <tom.hawtin at oracle.com> wrote:

> On a different topic, I wonder if it's fractionally better to write the 
> compare method as:
>             return
>                 a==b ? 0 :
>                 a==null ? (nullsFirst ? -1 : 1) :
>                 real.compare(a, b);

Putting my C2 hat on...  It is likely to be fractionally worse in many cases.  A 2-way pointer comparison is much more likely to remain in the generated code than the null comparisons (with 'a' and then 'b').

Tests of the form "x == null" are very likely to value-number (i.e., merge) with other tests in the same control flow, and such tests can also be merged (as implicit null checks) into dominating or trailing memory references "x.foo".  Adding the a==b?0 part would likely prevent a null check from being merged with a preceding "x.foo" reference, if there were one available.

Tests of the form "x == y" are less common, although if the real.compare call is inlined, there may be an equivalent short-circuit test inside the inlined method.  Or maybe not.  Omitting the hoisted a==b?0 would allow the real.compare method to decide whether or not to issue the pointer comparison.

Even though a pointer comparison is very cheap, it is much more expensive than nothing at all.  Worst case is the cost of the extra check is not amortized by work avoided by taken branches (the ?0 part).  This would occur when the comparator is used on a collection of all-distinct pointers.  That seems like a distinct possibility.

Rules of thumb for Java coders:  Simpler is better.  Null checks are cheap.

— John

More information about the lambda-dev mailing list