<p>clone() could be removed but the issue is whether the JVM does enough analysis to see that - I think enough inlining has to occur such that clone() is inlined right into bar() and then the JVM can see that it doesn&#39;t escape and the array is not mutated.  Either the allocation/copy is removed or at least becomes stack allocated.</p>

<p>Wrinkle with clone() is that it&#39;s virtual so if the inline cache is exceeded and regular vtbl call is made, we lose this ability; that&#39;s a more general case and shouldn&#39;t happen with things like bar().</p>

<p>Sent from my phone</p>
<div class="gmail_quote">On Mar 28, 2012 10:43 AM, &quot;Roel Spilker&quot; &lt;<a href="mailto:r.spilker@gmail.com">r.spilker@gmail.com</a>&gt; wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Rémi, are you sure the clone call can be removed? I agree that that would even be better for hotspot JVMs that use escape analysis. That said, apart from engineering effort, if a synthetic inner class is used you get the benefit immediately, even on VMs that cannot afford escape analysis.<div>

<br></div><div>Roel</div><div><br><br><div class="gmail_quote">On Wed, Mar 28, 2012 at 4:13 PM, Rémi Forax <span dir="ltr">&lt;<a href="mailto:forax@univ-mlv.fr" target="_blank">forax@univ-mlv.fr</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div>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></div></div>
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().<span><font color="#888888"><br>
<br>
Rémi<br>
<br>
<br>
<br>
<br>
</font></span></blockquote></div><br></div>
</blockquote></div>