Thanks for the great info, Ben.  One thing that occurred to me is that while 
delegates or lambdas would solve this problem, they do seem to go along with 
the 
.NET way of doing things: giving developers explicit control over memory 
allocation, similar to how .NET has an explicit "struct" construct in order to 
ensure stack allocation.  We theoretically get a stack allocation in Java as 
well, but only by way of runtime optimizations.  In other words, the language 
presents an illusion to the developer about certain simplicities of syntax and 
logic and allows the JVM to do some heavy lifting.  There are obviously some 
serious challenges for engineers working on the JVM's, and it can occasionally 
be frustrating to developers to not have that fine-grained control over 
runtime, 
but I think in the long run, we've seen this approach to be a beneficial (a la 
garbage collection evolution).

In the case of these stateless anonymous inner classes, I thought for sure it 
would fall into the same set of optimization targets as escape analysis.  I 
think stack allocation might be helpful as an optimization, but ultimately 
turning such an object into a lambda seems the way to go, since there are 
situations, where an object will be shared across threads, but is stateless 
nonetheless.  It will be interesting to see how this issue develops with JDK 7 
and 8 language changes.

 Alexey





________________________________
From: Ben Schulz <[email protected]>
To: The Java Posse <[email protected]>
Sent: Fri, April 29, 2011 9:26:20 AM
Subject: [The Java Posse] Re: question about JVM optimizations and 
instantiating 
stateless "function" objects

To answer the original question: No there is no such optimization.
Theoretically it can be optimized if the JIT can prove that the
object's identity is irrelevant (necessary due to[1]). Since you need
escape analysis for that, the JIT might as well just determine that
the object does not escape and stack allocate it. However, at this
point, objects that ArgEscape[2] still get heap allocated[3] (this
information is somewhat old, but afaik still accurate).

Anyways, this is one of the great things about lambdas: They won't be
instanciated via instance creation expressions and thus can be made
static without performing (successful) escape analysis.

With kind regards
Ben

[1] http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#23747
[2] http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.37.3797
[3] http://wikis.sun.com/display/HotSpotInternals/EscapeAnalysis

On 28 Apr., 19:52, Alexey Zinger <[email protected]> wrote:
> As I was looking at some code today that used FP concepts with Guava (Google
> Collections), I saw the same pattern I see over and over in such Java code 
that
> strives to be expressive in a functional manner: a function is required as a
> parameter for some operation and it so happens that the code that sends that
> function along instantiates the Guava Function object (or something similar,
> like Comparator) there and then.  The look of the code is as close to what we
> can expect to see in a "true" functional language with current Java
> capabilities, but more often than not, the purpose of including the guts of 
the
> function right there is to bundle the function definition with its logical
> context, not because we really need to instantiate the object in that place. 
> In
> fact, typically, the anonymous inner class expressing said function always
> produces identical instances.  Here's a hypothetical example.  Let's assume 
the
> following gets called a lot throughout the uptime of the program:
>
> final List<String> lowerCaseList = ...;
> final List<String> upperCaseList = Lists.transform(lowerCaseList, new
> Function<String, String>() {
>   public String apply(String s) { return s.toUpperCase(); }
>
> });
>
> This is quite readable, but in theory, the following would be more efficient:
>
> final List<String> lowerCaseList = "...";
> final List<String> upperCaseList = Lists.transform(lowerCaseList,
> toUpperFunction);
>
> where toUpperFunction is defined elsewhere, ensuring a more appropriate 
>lifespan
> to the instance.  Is there a JVM optimization that developers can reasonably
> rely on, that would effectively promote this particular apply(String)
> implementation to a "static" level, so that no instance memory would need to 
be
> allocated and reclaimed, and no constructor would need to be called?  And if
> not, is this on the order of magnitude, where it's generally not a concern in
> performance-sensitive scenarios?
>
> Alexeyhttp://azinger.blogspot.comhttp://bsheet.sourceforge.nethttp://wcollage.sourceforge.net
>t

-- 
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en.

-- 
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en.

Reply via email to