瀏覽代碼

Optimization of CalculateSize: avoid foreach over empty lists.

Jon Skeet 10 年之前
父節點
當前提交
1b71db1180

+ 1 - 5
src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc

@@ -89,13 +89,11 @@ void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer)
 
 
 void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
 void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
   // TODO(jonskeet): Move all this code into CodedOutputStream? It's a lot to repeat everywhere...
   // TODO(jonskeet): Move all this code into CodedOutputStream? It's a lot to repeat everywhere...
-  printer->Print("{\n");
-  printer->Indent();
   printer->Print(
   printer->Print(
     variables_,
     variables_,
-    "int dataSize = 0;\n"
     "if ($name$_.Count > 0) {\n");
     "if ($name$_.Count > 0) {\n");
   printer->Indent();
   printer->Indent();
+  printer->Print("int dataSize = 0;\n");
   printer->Print(
   printer->Print(
     variables_,
     variables_,
     "foreach ($type_name$ element in $name$_) {\n"
     "foreach ($type_name$ element in $name$_) {\n"
@@ -115,8 +113,6 @@ void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer
   }
   }
   printer->Outdent();
   printer->Outdent();
   printer->Print("}\n");
   printer->Print("}\n");
-  printer->Outdent();
-  printer->Print("}\n");
 }
 }
 
 
 void RepeatedEnumFieldGenerator::WriteHash(io::Printer* printer) {
 void RepeatedEnumFieldGenerator::WriteHash(io::Printer* printer) {

+ 4 - 2
src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc

@@ -90,8 +90,10 @@ void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* prin
   // TODO(jonskeet): Put this into CodedOutputStream.
   // TODO(jonskeet): Put this into CodedOutputStream.
   printer->Print(
   printer->Print(
     variables_,
     variables_,
-    "foreach ($type_name$ element in $name$_) {\n"
-    "  size += pb::CodedOutputStream.ComputeMessageSize($number$, element);\n"
+    "if ($name$_.Count > 0) {\n"
+    "  foreach ($type_name$ element in $name$_) {\n"
+    "    size += pb::CodedOutputStream.ComputeMessageSize($number$, element);\n"
+    "  }\n"
     "}\n");
     "}\n");
 }
 }
 
 

+ 5 - 5
src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc

@@ -93,7 +93,9 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(
 void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
 void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
     io::Printer* printer) {
     io::Printer* printer) {
   // TODO(jonskeet): Do this in the runtime if possible. It's a pain, but it must be feasible...
   // TODO(jonskeet): Do this in the runtime if possible. It's a pain, but it must be feasible...
-  printer->Print("{\n");
+  printer->Print(
+    "if ($name$_.Count > 0) {\n",
+    "name", name());
   printer->Indent();
   printer->Indent();
   printer->Print("int dataSize = 0;\n");
   printer->Print("int dataSize = 0;\n");
   int fixedSize = GetFixedSize(descriptor_->type());
   int fixedSize = GetFixedSize(descriptor_->type());
@@ -112,10 +114,8 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
   int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
   int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
   if (descriptor_->is_packed()) {
   if (descriptor_->is_packed()) {
     printer->Print(
     printer->Print(
-      "if ($name$_.Count != 0) {\n"
-      "  size += $tag_size$ + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);\n"
-      "}\n",
-      "name", name(), "tag_size", SimpleItoa(tagSize));
+      "size += $tag_size$ + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);\n",
+      "tag_size", SimpleItoa(tagSize));
   } else {
   } else {
     printer->Print(
     printer->Print(
       "size += $tag_size$ * $name$_.Count;\n",
       "size += $tag_size$ * $name$_.Count;\n",