Full java runtime: Avoid allocating ArrayList iterators when serializing UnknownFieldSet

Use old-style for loop instead.

This should speed up processes that serialize many unknown fields, and reduce some GC pressure.

PiperOrigin-RevId: 638889708
pull/16947/head
Mark Hansen 6 months ago committed by Copybara-Service
parent 094565b995
commit fac847c5c5
  1. 54
      java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java

@ -15,7 +15,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.TreeMap;
@ -778,40 +777,52 @@ public final class UnknownFieldSet implements MessageLite {
}
/** Serializes the field, including field number, and writes it to {@code output}. */
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"}) // No iterator allocation.
public void writeTo(int fieldNumber, CodedOutputStream output) throws IOException {
for (long value : varint) {
for (int i = 0; i < varint.size(); i++) {
long value = varint.get(i);
output.writeUInt64(fieldNumber, value);
}
for (int value : fixed32) {
for (int i = 0; i < fixed32.size(); i++) {
int value = fixed32.get(i);
output.writeFixed32(fieldNumber, value);
}
for (long value : fixed64) {
for (int i = 0; i < fixed64.size(); i++) {
long value = fixed64.get(i);
output.writeFixed64(fieldNumber, value);
}
for (ByteString value : lengthDelimited) {
for (int i = 0; i < lengthDelimited.size(); i++) {
ByteString value = lengthDelimited.get(i);
output.writeBytes(fieldNumber, value);
}
for (UnknownFieldSet value : group) {
for (int i = 0; i < group.size(); i++) {
UnknownFieldSet value = group.get(i);
output.writeGroup(fieldNumber, value);
}
}
/** Get the number of bytes required to encode this field, including field number. */
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"}) // No iterator allocation.
public int getSerializedSize(int fieldNumber) {
int result = 0;
for (long value : varint) {
for (int i = 0; i < varint.size(); i++) {
long value = varint.get(i);
result += CodedOutputStream.computeUInt64Size(fieldNumber, value);
}
for (int value : fixed32) {
for (int i = 0; i < fixed32.size(); i++) {
int value = fixed32.get(i);
result += CodedOutputStream.computeFixed32Size(fieldNumber, value);
}
for (long value : fixed64) {
for (int i = 0; i < fixed64.size(); i++) {
long value = fixed64.get(i);
result += CodedOutputStream.computeFixed64Size(fieldNumber, value);
}
for (ByteString value : lengthDelimited) {
for (int i = 0; i < lengthDelimited.size(); i++) {
ByteString value = lengthDelimited.get(i);
result += CodedOutputStream.computeBytesSize(fieldNumber, value);
}
for (UnknownFieldSet value : group) {
for (int i = 0; i < group.size(); i++) {
UnknownFieldSet value = group.get(i);
result += CodedOutputStream.computeGroupSize(fieldNumber, value);
}
return result;
@ -821,9 +832,11 @@ public final class UnknownFieldSet implements MessageLite {
* Serializes the field, including field number, and writes it to {@code output}, using {@code
* MessageSet} wire format.
*/
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"}) // No iterator allocation.
public void writeAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output)
throws IOException {
for (ByteString value : lengthDelimited) {
for (int i = 0; i < lengthDelimited.size(); i++) {
ByteString value = lengthDelimited.get(i);
output.writeRawMessageSetExtension(fieldNumber, value);
}
}
@ -854,17 +867,18 @@ public final class UnknownFieldSet implements MessageLite {
* Serializes the field, including field number, and writes it to {@code writer}, using {@code
* MessageSet} wire format.
*/
private void writeAsMessageSetExtensionTo(int fieldNumber, Writer writer)
throws IOException {
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"}) // No iterator allocation.
private void writeAsMessageSetExtensionTo(int fieldNumber, Writer writer) throws IOException {
if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
// Write in descending field order.
ListIterator<ByteString> iter = lengthDelimited.listIterator(lengthDelimited.size());
while (iter.hasPrevious()) {
writer.writeMessageSetItem(fieldNumber, iter.previous());
for (int i = lengthDelimited.size() - 1; i >= 0; i--) {
ByteString value = lengthDelimited.get(i);
writer.writeMessageSetItem(fieldNumber, value);
}
} else {
// Write in ascending field order.
for (ByteString value : lengthDelimited) {
for (int i = 0; i < lengthDelimited.size(); i++) {
ByteString value = lengthDelimited.get(i);
writer.writeMessageSetItem(fieldNumber, value);
}
}
@ -874,9 +888,11 @@ public final class UnknownFieldSet implements MessageLite {
* Get the number of bytes required to encode this field, including field number, using {@code
* MessageSet} wire format.
*/
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"}) // No iterator allocation.
public int getSerializedSizeAsMessageSetExtension(int fieldNumber) {
int result = 0;
for (ByteString value : lengthDelimited) {
for (int i = 0; i < lengthDelimited.size(); i++) {
ByteString value = lengthDelimited.get(i);
result += CodedOutputStream.computeRawMessageSetExtensionSize(fieldNumber, value);
}
return result;

Loading…
Cancel
Save