Avoid allocations in FieldSet.mergeFromField - Pre-size ArrayList - Avoid iterator allocation PiperOrigin-RevId: 653905397
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 9ddf548..debad4e 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 @@ } } - @SuppressWarnings({"unchecked", "rawtypes"}) + // Avoid iterator allocation. + @SuppressWarnings({"unchecked", "ForeachList", "ForeachListWithUserVar"}) private void mergeFromField(final Map.Entry<T, Object> entry) { final T descriptor = entry.getKey(); Object otherValue = entry.getValue(); @@ -528,11 +529,16 @@ 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<Object> list = (List<Object>) 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) {