Optimize bytecode for combination enhanced-for and enums

Jonathan Gibbons jonathan.gibbons at oracle.com
Wed Mar 28 07:20:37 PDT 2012


I note we have a lot of recent use cases of this pattern in our test cases.

-- Jon


On 03/28/2012 03:08 PM, Ulf Zibis wrote:
> 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