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