RFR: 8375561: Class NGGroup is in need of some cleanup [v2]
Michael Strauß
mstrauss at openjdk.org
Fri Jan 16 22:47:40 UTC 2026
On Fri, 16 Jan 2026 22:20:44 GMT, Andy Goryachev <angorya at openjdk.org> wrote:
>> Is that nowadays still not optimized internally to some degree? Since for each loops are so common now, I thought that the compiler would perform good enough optimizations.
>>
>> I chose for each loops here because the original issue was caused by the indicies in the for loop
>
> Optimization: I don't know. Maybe, maybe not. I suspect the contract is to create the iterator.
>
> My main point - it is a completely unnecessary change, a change for the sake of change.
An enhanced for-loop is syntactic sugar for:
Iterator<E> it = list.iterator();
while (it.hasNext()) {
E e = it.next();
...
}
If you look at the bytecode, you'll see that there is an object allocation. However, if C2 can prove via escape analysis that the iterator doesn't escape, it can
1. inline the `ArrayList.iterator()` call into the calling method, which is just a `new ArrayList$Itr()` expression,
2. scalarize the object allocation into locals, effectively storing `ArrayList$Itr`'s fields in the stack frame.
So yes, an enhanced for-loop can be optimized by the C2 compiler so that it doesn't allocate any memory. However, this is not a guarantee, and optimization may fail for a number of reasons:
1. The call site must be monomorphic, that means that the runtime profile of the call site only ever sees `ArrayList` here. If different concrete `List` classes are encountered at runtime, the call site becomes polymorphic or megamorphic and the method call can't be inlined.
2. The iterator can't be proven to not escape (stored somewhere, passed to a method, etc.)
3. The call-site method body is too large, so that inlining of `ArrayList.iterator()` doesn't happen.
All in all, it seems likely that iterator optimization will happen here. For clarity of intent, I would still recommend an indexed for-loop if you want to make sure that no object allocations happen at runtime, and I would also think in this case you should not repeatedly call the `List.size()` method, but just call it once:
for (int i = 0, max = list.size(); i < max; ++i) { // the intent here is obvious
...
}
-------------
PR Review Comment: https://git.openjdk.org/jfx/pull/2043#discussion_r2700229772
More information about the openjfx-dev
mailing list