Avoid allocations in FieldSet.setField

- Pre-size the ArrayList
- Avoid allocating iterator

Fix some rawtypes warnings too.

PiperOrigin-RevId: 653430395
pull/17456/head
Mark Hansen 8 months ago committed by Copybara-Service
parent bc03650b3e
commit ed54faf736
  1. 13
      java/core/src/main/java/com/google/protobuf/FieldSet.java

@ -264,7 +264,8 @@ final class FieldSet<T extends FieldSet.FieldDescriptorLite<T>> {
/**
* Useful for implementing {@link Message.Builder#setField(Descriptors.FieldDescriptor,Object)}.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
// Avoid iterator allocation.
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"})
public void setField(final T descriptor, Object value) {
if (descriptor.isRepeated()) {
if (!(value instanceof List)) {
@ -274,10 +275,14 @@ final class FieldSet<T extends FieldSet.FieldDescriptorLite<T>> {
// Wrap the contents in a new list so that the caller cannot change
// the list's contents after setting it.
final List newList = new ArrayList<>();
newList.addAll((List) value);
for (final Object element : newList) {
List<?> list = (List<?>) value;
int listSize = list.size();
// Avoid extra allocations: no iterator, no intermediate array copy.
final List<Object> newList = new ArrayList<>(listSize);
for (int i = 0; i < listSize; i++) {
Object element = list.get(i);
verifyType(descriptor, element);
newList.add(element);
}
value = newList;
} else {

Loading…
Cancel
Save