Skip to content

Commit 9eee325

Browse files
Microoptimize getSerializedSize() for repeated message fields by hoisting the encoded tag size constant to the gencode instead of recomputing it per value in the repeated.
While this should be a small optimization win post-JIT, this shape of behavior was previously added for every other non-packed repeated fields; the divergence of only repeated message fields not hoisting the tag size to protoc time seems likely to only be an oversight. Map fields are the other case which does not do this, but that is left for later work since that case may be able to be more 'deeply' better special cased since both the outer per-Entry tag size and the inner key/value tag sizes are known, but it is harder to trivialy do the 'inner' tag sizes safely since map entries are handled with or without implicit presence on the keys/values depending, which means the key tag and value tag may or may not be included at all based on both the map entry descriptor and the key/value contents. PiperOrigin-RevId: 850489334
1 parent 33b16e8 commit 9eee325

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

src/google/protobuf/compiler/java/full/message_field.cc

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "google/protobuf/compiler/java/helpers.h"
2323
#include "google/protobuf/compiler/java/name_resolver.h"
2424
#include "google/protobuf/io/printer.h"
25+
#include "google/protobuf/wire_format.h"
2526

2627
// Must be last.
2728
#include "google/protobuf/port_def.inc"
@@ -79,6 +80,9 @@ void SetMessageVariables(
7980
absl::StrCat(GenerateClearBit(builderBitIndex), ";");
8081
(*variables)["get_has_field_bit_from_local"] =
8182
GenerateGetBitFromLocal(builderBitIndex);
83+
84+
(*variables)["tag_size"] = absl::StrCat(
85+
internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
8286
}
8387

8488
} // namespace
@@ -783,8 +787,9 @@ void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers(
783787

784788
void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
785789
io::Printer* printer) const {
786-
printer->Print(variables_, "@SuppressWarnings(\"serial\")\n"
787-
"private java.util.List<$type$> $name$_;\n");
790+
printer->Print(variables_,
791+
"@SuppressWarnings(\"serial\")\n"
792+
"private java.util.List<$type$> $name$_;\n");
788793
PrintExtraFieldInfo(variables_, printer);
789794
WriteFieldDocComment(printer, descriptor_, context_->options());
790795
printer->Print(variables_,
@@ -1275,12 +1280,17 @@ void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode(
12751280

12761281
void RepeatedImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
12771282
io::Printer* printer) const {
1278-
printer->Print(
1279-
variables_,
1280-
"for (int i = 0; i < $name$_.size(); i++) {\n"
1281-
" size += com.google.protobuf.CodedOutputStream\n"
1282-
" .compute$group_or_message$Size($number$, $name$_.get(i));\n"
1283-
"}\n");
1283+
printer->Print(variables_,
1284+
R"java(
1285+
{
1286+
final int count = $name$_.size();
1287+
for (int i = 0; i < count; i++) {
1288+
size += com.google.protobuf.CodedOutputStream
1289+
.compute$group_or_message$SizeNoTag($name$_.get(i));
1290+
}
1291+
size += $tag_size$ * count;
1292+
}
1293+
)java");
12841294
}
12851295

12861296
void RepeatedImmutableMessageFieldGenerator::GenerateEqualsCode(

0 commit comments

Comments
 (0)