RFR: 8166365: Small immutable collections should provide optimized implementations when possible
Louis Wasserman
wasserman.louis at gmail.com
Wed Jan 11 22:30:45 UTC 2017
I haven't followed this much, but an observation: in Guava, we avoided
creating lots of specialized implementations for small collections, because
the JVM, at least at the time, had a sweet spot for bimorphic dispatch:
method calls where the real implementation would be one of two options, and
that the cost blew up after you hit three, and we considered hitting that
sweet spot more worthwhile than the slightly smaller overhead for
collections that were already small.
As a result, many of our immutable collection implementations converged on
having two implementations: one single-element implementation, and one
implementation for everything else (0, 2, 3... but not 1), and then we had
a singleton static constant object for the 0-element case.
I don't know if that calculus has changed, but it seemed worth mentioning.
On Wed, Jan 11, 2017 at 10:06 AM Martin Buchholz <martinrb at google.com>
wrote:
> On Wed, Jan 11, 2017 at 5:43 AM, Claes Redestad <claes.redestad at oracle.com
> >
> wrote:
>
> >
> >> -------
> >>
> >> In Set2, SetN, Map1, and MapN, the addition of @Stable also dropped the
> >> "private" access modifier. Other implementations still have
> corresponding
> >> fields as private. Was this intentional? I think they should all remain
> >> private.
> >>
> >
> > This was intentional: for those implementations where I dropped private
> > there are inner
> > classes which access the fields directly. This leads to synthetic
> > accessors, which shows up
> > as JIT compilation overhead during module bootstrap profiling.
> >
>
> In java.util.concurrent, our policy is to avoid creating synthetic
> accessors, so we also promote private to package private when accessed by
> nested classes, and this seems to be the best engineering compromise...
> (until we get nestmates?)
>
>
> > This is what made me look at this in the first place, and a large part of
> > the reason why I
> > believe that it's motivated to fast-track this enhancement as a means to
> > improve JDK 9
> > startup metrics. If you have a strong preference against them being made
> > package-private
> > there's a similar gain to be had by passing them as arguments to concrete
> > inner classes,
> > e.g., for Set2:
> >
> > static class Itr<E> implements Iterator<E> {
> > private final E e0;
> > private final E e1;
> > private int idx = 0;
> > Itr(E e0, E e1) {
> > this.e0 = e0;
> > this.e1 = e1;
> > }
> > @Override
> > public boolean hasNext() {
> > return idx < 2;
> > }
> >
> > @Override
> > public E next() {
> > if (idx == 0) {
> > idx = 1;
> > return e0;
> > } else if (idx == 1) {
> > idx = 2;
> > return e1;
> > } else {
> > throw new NoSuchElementException();
> > }
> > }
> > }
> >
> > @Override
> > public Iterator<E> iterator() {
> > return new Itr<E>(e0, e1);
> > }
> >
>
More information about the core-libs-dev
mailing list