Avoid allocations in FieldSet.mergeFromField

- Pre-size ArrayList
- Avoid iterator allocation

PiperOrigin-RevId: 653905397
pull/17460/head
Mark Hansen 4 months ago committed by Copybara-Service
parent 8995b485b9
commit 1f005c579f
  1. 14
      java/core/src/main/java/com/google/protobuf/FieldSet.java

@ -517,7 +517,8 @@ final class FieldSet<T extends FieldSet.FieldDescriptorLite<T>> {
} }
} }
@SuppressWarnings({"unchecked", "rawtypes"}) // Avoid iterator allocation.
@SuppressWarnings({"unchecked", "ForeachList", "ForeachListWithUserVar"})
private void mergeFromField(final Map.Entry<T, Object> entry) { private void mergeFromField(final Map.Entry<T, Object> entry) {
final T descriptor = entry.getKey(); final T descriptor = entry.getKey();
Object otherValue = entry.getValue(); Object otherValue = entry.getValue();
@ -528,11 +529,16 @@ final class FieldSet<T extends FieldSet.FieldDescriptorLite<T>> {
throw new IllegalStateException("Lazy fields can not be repeated"); throw new IllegalStateException("Lazy fields can not be repeated");
} }
Object value = getField(descriptor); Object value = getField(descriptor);
List<?> otherList = (List<?>) otherValue;
int otherListSize = otherList.size();
if (value == null) { if (value == null) {
value = new ArrayList<>(); value = new ArrayList<>(otherListSize);
} }
for (Object element : (List) otherValue) { List<Object> list = (List<Object>) value;
((List) value).add(cloneIfMutable(element)); // Avoid iterator allocation.
for (int i = 0; i < otherListSize; i++) {
Object element = otherList.get(i);
list.add(cloneIfMutable(element));
} }
fields.put(descriptor, value); fields.put(descriptor, value);
} else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {

Loading…
Cancel
Save