Optimize bytecode for combination enhanced-for and enums

Ulf Zibis Ulf.Zibis at gmx.de
Wed Mar 28 07:08:04 PDT 2012


Interesting catch!
I'm too curious about the answers from the specialists.

-Ulf


Am 28.03.2012 15:39, schrieb Roel Spilker:
> Hi all,
>
> 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?
>
> I'm new to this list, so please let me know if this is not the place to post this.
>
> When I was profiling our application I notices that we allocate quite some memory when iterating 
> over enum values. The pattern used was:
>
> class  Foo {
>   void bar() {
>     for (Edge e : Edge.values()) {
>       // do some work
>     }
>   }
> }
>
> The call to Edge.values() obviously creates a new clone of the Edge[] containing all enum 
> constants. So we've modified our code:
>
> class  Foo {
>   private static final Edge[] EDGES = Edge.values();
>   void bar() {
>     for (Edge e : EDGES) {
>       // do some work
>     }
>   }
> }
>
> 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:
>
> /* syncthetic */ class Foo$0 {
>   static final Edge[] EDGES = Edge.values();
> }
>
> class  Foo {
>   void bar() {
>     for (Edge e : Foo$0.EDGES) {
>       // do some work
>     }
>   }
> }
>
> 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.
>
> I have a few questions:
> - 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.
> - Is there a better optimization possible/required? EnumSet 
> uses SharedSecrets.getJavaLangAccess().getEnumConstantsShared(elementType), but that won't work in 
> user code.
> - If it is a good idea, how do I proceed from here? Possibly create a JEP? How can I contribute? 
> Who wants to support?
>
> Roel Spilker
>



More information about the compiler-dev mailing list