RFR JDK-8011200 (was 7143928) : (coll) Optimize for Empty ArrayList and HashMap

Martin Buchholz martinrb at google.com
Wed Apr 10 21:26:48 UTC 2013


I'm willing to accept John as an authority on hotspot optimization.
I'm surprised that null checks aren't more close to free in part because
recent jsr166 code has been introducing more explicit null checks,
sometimes in code where the reference being checked is "known" not to be
null.

Martin


On Wed, Apr 10, 2013 at 11:12 AM, Mike Duigou <mike.duigou at oracle.com>wrote:

>
> On Apr 9 2013, at 19:56 , Martin Buchholz wrote:
> The use of an empty array rather than null was suggested by John Rose who
> said:
>
> I recommend an empty array rather than null as a sentinel value for two
> reasons:
>
> 1. The JVM prefers to merge null checks into load or store instructions
> (so-called "implicit null checks") because it removes an explicit branch.
> But it only does so if the probability of nulls is zero or very low. But
> using null as a sentinel for common states (e.g., empty collection) defeats
> this optimization.
>
> 2. For power-of-two sized structures (HashMap) we can optimize away an
> array range check in the presence of a zero-length check.
>
> Since most uses of a variable-sized collection load and test the array
> length, the sentinel check can easily be overloaded onto this test. If null
> is not used, then the (safety-mandated) null check is (usually) merged into
> the load of the length. If the table is power-of-two-sized, then only the
> zero check remains, and the array range check may be removed. This is
> thought to be the best code for a frequent load from a possibly-empty
> collection.
>
> Mike asked, "what about empty collection?" This is a reasonable thing to
> use, but it has a cost. The JVM uses inline caches and type profiles to
> simplify its optimized code; these techniques "win" when at a given use
> point (individual call to Map.get, for example) there is only one class
> present, even if the interface is totally general. (This is the so-called
> "monomorphic" case.) If the application uses (say) only HashMaps for both
> empty and non-empty maps, then this optimization can win big. It can be
> broken, on the other hand, if the application begins to use one other type
> for some other case (such as empty maps). In these cases, it is better to
> overload the "am I empty?" test on some other loaded value, such as a null
> or (better) an array length.
>
>
> Mike
>



More information about the core-libs-dev mailing list