Simplifying reified generics with partial specialization

Ron Pressler ron at paralleluniverse.co
Mon Jan 5 17:45:35 UTC 2015


To handle high-order functions, you can employ one of two solutions: either
rely on JVM optimization to elide boxing, or, if that's too hard for the
JVM, you can make use of the imperfect but currently acceptable solution of
bridge methods. In the latter case, IntBinaryOperator would extend
BinaryOperator<Integer> and the lambda expression would generate a bridge
method for the boxed case. The specialized ArrayList<int> (and its
resulting stream) would call the applyAsInt method thus eliding the boxing
at compile time rather than relying on the JVM to optimize it at runtime.
All of this specialization is hidden in the specialized implementation
without changing the public API.

I realize I'm probably glossing over some details, but this generation of
bridge methods and specialized call to the specialized method would still
be easier -- both to implement and to use -- than layers. Of course, there
might be some missing pieces here which would make this approach
unworkable, but it requires more careful consideration.


Ron Pressler
paralleluniverse.co
@puniverseco <https://twitter.com/puniverseco> on Twitter

On Mon, Jan 5, 2015 at 5:28 PM, Tomas Mikula <tomas.mikula at gmail.com> wrote:

> On Mon, Jan 5, 2015 at 1:10 PM, Ron Pressler <ron at paralleluniverse.co>
> wrote:
> > Hi. I've been following the discussion here, and I think there's a simple
> > solution that will satisfy everyone: [...]
> >
> > The idea is simple: a generic instantiation over a value type would
> > specialize fields (and array fields, obviously) and local variables, but
> > not arguments and return values of non-private methods.
>
> This does not let us enjoy a performance gain in higher-order
> operations, such as summing a Stream<int> using Stream#reduce:
>
> Stream<int> stream;
> stream.reduce(0, (a, b) -> a + b);
>
> The second argument to the reduce method has the type
> BinaryOperator<int>, whose method
>
> T apply(T a, T b)
>
> is actualy
>
> Integer apply(Integer a, Integer b);
>
> as argument types and return types are not specialized as per your
> proposal. Thus, all ints in the specialized Stream still have to be
> boxed to be passed to the apply method, then unboxed inside the apply
> method for the + operator, whose result is again boxed as a return
> value of apply.
>
> Regards,
> Tomas
>


More information about the valhalla-dev mailing list