Logging API
Brian Goetz
brian.goetz at oracle.com
Tue May 22 13:48:05 PDT 2012
> I'd also note that the primary goal of such a change is performance,
> and the story there isn't as perfect as you might prefer. Capturing
> a lambda which captures variables from the enclosing scope has a
> cost, comparable to an object allocation. (On the other hand,
> capturing non-capturing lambdas, which will be the common case for
> many filter/map/reduce type of operations, should be basically
> free.) So while you defer creating the string until you need it,
> you do not necessarily defer creating the lambda (though the VM may
> be able to optimize that away in some cases.) So the
> "Factory<String> approach" will be faster than just precomputing the
> string unconditionally, but probably slower than the commonly used
> trick of preceding the logging call with an "if (logger.level() >=
> DEBUG)" statement. So if you were thinking this would be a totally
> free way to replace those ugly if statements, you might be disappointed.
>
> The log(Level, String, Object) method in the Oracle JDK does as its
> first statement:
>
> if (level.intValue() < levelValue || levelValue == offValue) {
> return;
> }
>
> I think Hotspot is currently able to inline that method. It also seems
> like allocating a lambda should be side-effect free. If so, might we
> expect the VM to be smart enough in JDK 8 to know that it can push the
> allocation inside that 'if' (assuming it's not used for anything else)?
HotSpot is certainly *able* to inline the method. There is no guarantee
that it will *always* inline the method. If it does not, the capture
costs will have to be paid regardless of use.
Assume it inlines the method. It does indeed seem that allocating a
lambda should be side-effect free. It is also easy for HotSpot to
recognize lambda captures in the bytecode (they are invokedynamic call
sites with a well-known bootstrap method.) We certainly do intend to
make the VM smart enough to know this, which would allow code motion so
as to push the capture until the latest possible time (into the "if"),
and, if escape analysis says it is OK, to do "box elision" on the lambda
object and turn the virtual method invocation into a direct MH
invocation on the underlying desugared lambda body, and then optimize
away the lambda capture entirely. Which would be pretty close to free.
Would we like to do that? Of course. Do we know how? Yes. Can we do
it for JDK 8, with our current resourcing situation and current and
future competing priorities? Can't say. Let's just say it's not
guaranteed that all the possible optimizations we'd like to do will be
done for JDK 8, which motivated my caveats about the performance
characteristics of the idiom you were requesting, just in case you might
have been under the impression that it would be free and wanting to save
you some disappointment.
More information about the lambda-dev
mailing list