Lambda Conversion Considered Harmful?

Osvaldo Doederlein opinali at gmail.com
Fri Feb 19 05:44:16 PST 2010


Wow, it's great being able to agree with both Josh and Neal, this will raise
my karma in at least 10 points. ;-) We definitely cannot have any perf
regression for any lambda usage that replaces existing idioms, not even
"only" for SAM type use-cases that could be sweeped under the rug of
"backwards compatibility" - in practice this use-case will be vastly
predominant for many years to come.

I have exposed the opinion that lambdas could be a great opportunity to have
_better_ performance than traditional idioms - either by allowing the
compiler to aggressive inline control abstractions and other uses of
literal, "soft" lambdas; or because lambdas may be compiled into
MethodHandles which may be lightweight compared to bulky synthetic classes -
but if this is not possible for any reason, we must at the very least follow
Hippocrates' rule "first, do no harm" performance-wise.

Considering this, my -1 to the hideously convoluted techniques that I see in
proposals related to function types vs. arrays and lambda reification. The
hacker inside me admires this ingenuity (assuming that it works), but the
smell of complexity and bloat is just unbearable - and I though inner
classes were bad. Call me old-fashioned, but if a couple lines of lambda
code is desugared into multiple pages of Java code - even if most of it is
adapter methods that can be reused in a few other usage sites with identical
signatures - that's Just Wrong. Believe me, lambdas will be D.O.A. if, when
SE7 ships, people start blogging that they updated some app that uses a lot
of inner classes to use lambdas, and the resulting JAR file was +50% the old
size. (Profile-driven, dynamic translation could be better, if it doesn't
introduce new issues.)

A+
Osvaldo

2010/2/19 Joshua Bloch <jjb at google.com>

> As I'm sure you're aware, I'm very much in favor of the goal of the Lambda
> conversion: the new syntax (or something like it) should be usable in
> combination with existing constructs that require a "function object" such
> as a Comparator or (perhaps) a TimerTask.  But I'm increasingly skeptical
> that the Lambda conversion (as described in the proposal) is the best way
> to
> achieve this.
>
> I'm skeptical for two reasons. The first concerns the semantics. Simply
> put,
> function types just get in the way when what you want is a SAM type. They
> raise all sorts of thorny issues, many of which we've been discussing
> recently. Is the function-typed object the same object as the SAM-typed
> object, or are there two objects involved? Is there any way to access the
> members of the SAM type? And so on.
>
> The second reason I'm skeptical concerns performance.  The latest spec
> draft
> says this:
>
> Implementing lambda conversion will likely generate new objects to wrap or
> > delegate to the lambda expression. This is acceptable in assignment and
> > method invocation conversion contexts, but not in a casting conversion
> > context. (See
> >
> http://mail.openjdk.java.net/pipermail/lambda-dev/2010-January/000449.html
> > )
>
>
> I fear that this will have disastrous performance consequences. Presented
> with a lovely new syntax, programmers will naturally use it, e.g., to make
> Comparators:
>
>    Arrays.sort(a, #(String s1, String s2)(return s1.length - s2.length));
>
> But the comparator's sole method is invoked in the inner loop of the sort!
> The slowdown caused by the delegation will add to the constant factor of
> the
> (n log n) sort. This could be very costly! I believe it violates a
> fundamental tenet of Java's design, which has been called *transparency*:
>  magic should be kept to a minimum, and the code should reflect its
> performance (to the extent that that's feasible in this day and age). The
> for-each loop, by contrast, does not create an Iterator when traversing an
> array, so it runs as fast as the traditional for loop that it replaces.
> This
> was very important to me when we were designing the for-each construct, and
> I'm glad we did it the way we did.
>
> Therefore, I think we should *very *seriously consider an alternative
> design
> that uses a slightly different syntax when furnishing instances of SAM
> types
> that it does when furnishing instances of function types.  Call them
> SAM-lambdas and function-lambads (for the time being). Perhaps the SAM
> lambdas could take the type as a mandatory argument, to simplify the
> compiler's job:
>
>    Arrays.sort(a, #Comparator(String s1, String s2)(return s1.length -
> s2.length));
>
> I have no idea whether this is the best syntax, or even an acceptable
> syntax.  The important point is that we need something that:
>
>   (1) Interoperates with existing methods that require "function objects"
>   (2) Provides performance equal to current idioms, and
>   (3) Provide conciseness close to that of lambdas (as specified in the
> current proposal)
>
> As a clarification, I am not arguing for the elimination of function types;
> rather I'm arguing that they get in the way of "interoperable function
> objects." so we need two separate syntaxes, one for function types and one
> for SAM types.
>
>             Josh
>
>


More information about the lambda-dev mailing list