<p>The synthetic class can be marked static to ensure it only inits in bar().  However I agree about it staying too long.  Plus you&#39;d really want the synthetic generated inside the enum class rather than in callsite classes.</p>

<p>I also think escape analysis would be ideal because it can apply to not just enum use cases but this pattern in general.</p>
<p>Sent from my phone</p>
<div class="gmail_quote">On Mar 28, 2012 10:12 AM, &quot;Rémi Forax&quot; &lt;<a href="mailto:forax@univ-mlv.fr">forax@univ-mlv.fr</a>&gt; wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On 03/28/2012 03:39 PM, Roel Spilker wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi all,<br>
<br>
TL;DR: for (Edge edge : Edge.values()) copies an array every time it is executed. This can be prevented. Is that a good idea and how to proceed from here?<br>
<br>
I&#39;m new to this list, so please let me know if this is not the place to post this.<br>
<br>
When I was profiling our application I notices that we allocate quite some memory when iterating over enum values. The pattern used was:<br>
<br>
class  Foo {<br>
  void bar() {<br>
    for (Edge e : Edge.values()) {<br>
      // do some work<br>
    }<br>
  }<br>
}<br>
<br>
The call to Edge.values() obviously creates a new clone of the Edge[] containing all enum constants. So we&#39;ve modified our code:<br>
<br>
class  Foo {<br>
  private static final Edge[] EDGES = Edge.values();<br>
  void bar() {<br>
    for (Edge e : EDGES) {<br>
      // do some work<br>
    }<br>
  }<br>
}<br>
<br>
This solves our allocation problem, but it is not a nice solution. Since code in the enhanced-for has no way to modify the array this pattern can be done at compile-time. A synthetic inner class can be generated to keep the copy of the array. The desugared (pseudo) code would then look something like this:<br>

<br>
/* syncthetic */ class Foo$0 {<br>
  static final Edge[] EDGES = Edge.values();<br>
}<br>
<br>
class  Foo {<br>
  void bar() {<br>
    for (Edge e : Foo$0.EDGES) {<br>
      // do some work<br>
    }<br>
  }<br>
}<br>
<br>
There is precedence for this kind of desugaring/optimization: When you use an enum-in-switch, a synthetic class is generated containing an int array for the ordinals.<br>
<br>
I have a few questions:<br>
- Do you think this is a good optimization? The trade-off here is creating a copy every time the enhanced-for is used (could be in an inner loop) versus the overhead of loading an extra class.<br>
- Is there a better optimization possible/required? EnumSet uses SharedSecrets.<u></u>getJavaLangAccess().<u></u>getEnumConstantsShared(<u></u>elementType), but that won&#39;t work in user code.<br>
- If it is a good idea, how do I proceed from here? Possibly create a JEP? How can I contribute? Who wants to support?<br>
<br>
Roel Spilker<br>
<br>
</blockquote>
<br>
Hi Roel,<br>
There are several issues with your template, EDGES is initialized too soon, i.e.<br>
even if you don&#39;t call bar() and stay too long, i.e even if you never call bar() more than once.<br>
<br>
I think it&#39;s better to let the the escape analysis pass done by the JIT to inline<br>
values() and remove the call to clone().<br>
<br>
Rémi<br>
<br>
<br>
<br>
<br>
</blockquote></div>