From 1f005c579fb1db964530cf537befad4bd83c8c44 Mon Sep 17 00:00:00 2001 From: Mark Hansen Date: Fri, 19 Jul 2024 00:34:05 -0700 Subject: [PATCH] Avoid allocations in FieldSet.mergeFromField - Pre-size ArrayList - Avoid iterator allocation PiperOrigin-RevId: 653905397 --- .../main/java/com/google/protobuf/FieldSet.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/java/core/src/main/java/com/google/protobuf/FieldSet.java b/java/core/src/main/java/com/google/protobuf/FieldSet.java index 9ddf548865..debad4e971 100644 --- a/java/core/src/main/java/com/google/protobuf/FieldSet.java +++ b/java/core/src/main/java/com/google/protobuf/FieldSet.java @@ -517,7 +517,8 @@ final class FieldSet> { } } - @SuppressWarnings({"unchecked", "rawtypes"}) + // Avoid iterator allocation. + @SuppressWarnings({"unchecked", "ForeachList", "ForeachListWithUserVar"}) private void mergeFromField(final Map.Entry entry) { final T descriptor = entry.getKey(); Object otherValue = entry.getValue(); @@ -528,11 +529,16 @@ final class FieldSet> { throw new IllegalStateException("Lazy fields can not be repeated"); } Object value = getField(descriptor); + List otherList = (List) otherValue; + int otherListSize = otherList.size(); if (value == null) { - value = new ArrayList<>(); + value = new ArrayList<>(otherListSize); } - for (Object element : (List) otherValue) { - ((List) value).add(cloneIfMutable(element)); + List list = (List) value; + // Avoid iterator allocation. + for (int i = 0; i < otherListSize; i++) { + Object element = otherList.get(i); + list.add(cloneIfMutable(element)); } fields.put(descriptor, value); } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {