Skip to content

Commit

Permalink
Full java runtime: Avoid allocating ArrayList iterators when serializ…
Browse files Browse the repository at this point in the history
…ing 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
  • Loading branch information
mhansen authored and copybara-github committed May 31, 2024
1 parent 094565b commit fac847c
Showing 1 changed file with 35 additions and 19 deletions.
54 changes: 35 additions & 19 deletions java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.TreeMap;

Expand Down Expand Up @@ -778,40 +777,52 @@ public ByteString toByteString(int fieldNumber) {
}

/** 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;
Expand All @@ -821,9 +832,11 @@ public int getSerializedSize(int fieldNumber) {
* 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);
}
}
Expand Down Expand Up @@ -854,17 +867,18 @@ void writeTo(int fieldNumber, Writer writer) throws IOException {
* 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);
}
}
Expand All @@ -874,9 +888,11 @@ private void writeAsMessageSetExtensionTo(int fieldNumber, Writer writer)
* 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;
Expand Down

0 comments on commit fac847c

Please sign in to comment.