Skip to content

Commit

Permalink
Java full runtime: Avoid allocating iterator if UnknownFieldSet's Tre…
Browse files Browse the repository at this point in the history
…eMap is empty

I also considered using Collections.emptyNavigableMap(), which I thought might
use a specialized allocation free empty iterator, but it allocates, and its
clone() method isn't nicely exposed.

PiperOrigin-RevId: 630234849
  • Loading branch information
mhansen authored and copybara-github committed May 3, 2024
1 parent cc79f77 commit 4f12891
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 additions & 4 deletions java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ public Field getField(int number) {
/** Serializes the set and writes it to {@code output}. */
@Override
public void writeTo(CodedOutputStream output) throws IOException {
if (fields.isEmpty()) {
// Avoid allocating an iterator.
return;
}
for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
Field field = entry.getValue();
field.writeTo(entry.getKey(), output);
Expand Down Expand Up @@ -174,23 +178,33 @@ public void writeDelimitedTo(OutputStream output) throws IOException {
@Override
public int getSerializedSize() {
int result = 0;
if (!fields.isEmpty()) {
for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
result += entry.getValue().getSerializedSize(entry.getKey());
}
if (fields.isEmpty()) {
// Avoid allocating an iterator.
return result;
}
for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
result += entry.getValue().getSerializedSize(entry.getKey());
}
return result;
}

/** Serializes the set and writes it to {@code output} using {@code MessageSet} wire format. */
public void writeAsMessageSetTo(CodedOutputStream output) throws IOException {
if (fields.isEmpty()) {
// Avoid allocating an iterator.
return;
}
for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), output);
}
}

/** Serializes the set and writes it to {@code writer}. */
void writeTo(Writer writer) throws IOException {
if (fields.isEmpty()) {
// Avoid allocating an iterator.
return;
}
if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
// Write fields in descending order.
for (Map.Entry<Integer, Field> entry : fields.descendingMap().entrySet()) {
Expand All @@ -206,6 +220,10 @@ void writeTo(Writer writer) throws IOException {

/** Serializes the set and writes it to {@code writer} using {@code MessageSet} wire format. */
void writeAsMessageSetTo(Writer writer) throws IOException {
if (fields.isEmpty()) {
// Avoid allocating an iterator.
return;
}
if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
// Write fields in descending order.
for (Map.Entry<Integer, Field> entry : fields.descendingMap().entrySet()) {
Expand All @@ -222,6 +240,10 @@ void writeAsMessageSetTo(Writer writer) throws IOException {
/** Get the number of bytes required to encode this set using {@code MessageSet} wire format. */
public int getSerializedSizeAsMessageSet() {
int result = 0;
if (fields.isEmpty()) {
// Avoid allocating an iterator.
return result;
}
for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
result += entry.getValue().getSerializedSizeAsMessageSetExtension(entry.getKey());
}
Expand Down

0 comments on commit 4f12891

Please sign in to comment.