Skip to content

Commit fac847c

Browse files
mhansencopybara-github
authored andcommitted
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
1 parent 094565b commit fac847c

File tree

1 file changed

+35
-19
lines changed

1 file changed

+35
-19
lines changed

java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import java.util.Arrays;
1616
import java.util.Collections;
1717
import java.util.List;
18-
import java.util.ListIterator;
1918
import java.util.Map;
2019
import java.util.TreeMap;
2120

@@ -778,40 +777,52 @@ public ByteString toByteString(int fieldNumber) {
778777
}
779778

780779
/** Serializes the field, including field number, and writes it to {@code output}. */
780+
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"}) // No iterator allocation.
781781
public void writeTo(int fieldNumber, CodedOutputStream output) throws IOException {
782-
for (long value : varint) {
782+
for (int i = 0; i < varint.size(); i++) {
783+
long value = varint.get(i);
783784
output.writeUInt64(fieldNumber, value);
784785
}
785-
for (int value : fixed32) {
786+
for (int i = 0; i < fixed32.size(); i++) {
787+
int value = fixed32.get(i);
786788
output.writeFixed32(fieldNumber, value);
787789
}
788-
for (long value : fixed64) {
790+
for (int i = 0; i < fixed64.size(); i++) {
791+
long value = fixed64.get(i);
789792
output.writeFixed64(fieldNumber, value);
790793
}
791-
for (ByteString value : lengthDelimited) {
794+
for (int i = 0; i < lengthDelimited.size(); i++) {
795+
ByteString value = lengthDelimited.get(i);
792796
output.writeBytes(fieldNumber, value);
793797
}
794-
for (UnknownFieldSet value : group) {
798+
for (int i = 0; i < group.size(); i++) {
799+
UnknownFieldSet value = group.get(i);
795800
output.writeGroup(fieldNumber, value);
796801
}
797802
}
798803

799804
/** Get the number of bytes required to encode this field, including field number. */
805+
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"}) // No iterator allocation.
800806
public int getSerializedSize(int fieldNumber) {
801807
int result = 0;
802-
for (long value : varint) {
808+
for (int i = 0; i < varint.size(); i++) {
809+
long value = varint.get(i);
803810
result += CodedOutputStream.computeUInt64Size(fieldNumber, value);
804811
}
805-
for (int value : fixed32) {
812+
for (int i = 0; i < fixed32.size(); i++) {
813+
int value = fixed32.get(i);
806814
result += CodedOutputStream.computeFixed32Size(fieldNumber, value);
807815
}
808-
for (long value : fixed64) {
816+
for (int i = 0; i < fixed64.size(); i++) {
817+
long value = fixed64.get(i);
809818
result += CodedOutputStream.computeFixed64Size(fieldNumber, value);
810819
}
811-
for (ByteString value : lengthDelimited) {
820+
for (int i = 0; i < lengthDelimited.size(); i++) {
821+
ByteString value = lengthDelimited.get(i);
812822
result += CodedOutputStream.computeBytesSize(fieldNumber, value);
813823
}
814-
for (UnknownFieldSet value : group) {
824+
for (int i = 0; i < group.size(); i++) {
825+
UnknownFieldSet value = group.get(i);
815826
result += CodedOutputStream.computeGroupSize(fieldNumber, value);
816827
}
817828
return result;
@@ -821,9 +832,11 @@ public int getSerializedSize(int fieldNumber) {
821832
* Serializes the field, including field number, and writes it to {@code output}, using {@code
822833
* MessageSet} wire format.
823834
*/
835+
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"}) // No iterator allocation.
824836
public void writeAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output)
825837
throws IOException {
826-
for (ByteString value : lengthDelimited) {
838+
for (int i = 0; i < lengthDelimited.size(); i++) {
839+
ByteString value = lengthDelimited.get(i);
827840
output.writeRawMessageSetExtension(fieldNumber, value);
828841
}
829842
}
@@ -854,17 +867,18 @@ void writeTo(int fieldNumber, Writer writer) throws IOException {
854867
* Serializes the field, including field number, and writes it to {@code writer}, using {@code
855868
* MessageSet} wire format.
856869
*/
857-
private void writeAsMessageSetExtensionTo(int fieldNumber, Writer writer)
858-
throws IOException {
870+
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"}) // No iterator allocation.
871+
private void writeAsMessageSetExtensionTo(int fieldNumber, Writer writer) throws IOException {
859872
if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
860873
// Write in descending field order.
861-
ListIterator<ByteString> iter = lengthDelimited.listIterator(lengthDelimited.size());
862-
while (iter.hasPrevious()) {
863-
writer.writeMessageSetItem(fieldNumber, iter.previous());
874+
for (int i = lengthDelimited.size() - 1; i >= 0; i--) {
875+
ByteString value = lengthDelimited.get(i);
876+
writer.writeMessageSetItem(fieldNumber, value);
864877
}
865878
} else {
866879
// Write in ascending field order.
867-
for (ByteString value : lengthDelimited) {
880+
for (int i = 0; i < lengthDelimited.size(); i++) {
881+
ByteString value = lengthDelimited.get(i);
868882
writer.writeMessageSetItem(fieldNumber, value);
869883
}
870884
}
@@ -874,9 +888,11 @@ private void writeAsMessageSetExtensionTo(int fieldNumber, Writer writer)
874888
* Get the number of bytes required to encode this field, including field number, using {@code
875889
* MessageSet} wire format.
876890
*/
891+
@SuppressWarnings({"ForeachList", "ForeachListWithUserVar"}) // No iterator allocation.
877892
public int getSerializedSizeAsMessageSetExtension(int fieldNumber) {
878893
int result = 0;
879-
for (ByteString value : lengthDelimited) {
894+
for (int i = 0; i < lengthDelimited.size(); i++) {
895+
ByteString value = lengthDelimited.get(i);
880896
result += CodedOutputStream.computeRawMessageSetExtensionSize(fieldNumber, value);
881897
}
882898
return result;

0 commit comments

Comments
 (0)