浏览代码

Use fixed size for bool, float and double field in codec (#5810)

* Improve C# serialization performance of repeated fields for primitives.

* Changes based on feedback.

* Change compatibility tests to chec float, bool and double are fixed

* Changes based on feedback.

* In the compute methods use the newly created constants
WilliamWhispell 6 年之前
父节点
当前提交
59284450fa

+ 3 - 3
csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/FieldCodecTest.cs

@@ -43,7 +43,7 @@ namespace Google.Protobuf
 #pragma warning disable 0414 // Used by tests via reflection - do not remove!
         private static readonly List<ICodecTestData> Codecs = new List<ICodecTestData>
         {
-            new FieldCodecTestData<bool>(FieldCodec.ForBool(100), true, "Bool"),
+            new FieldCodecTestData<bool>(FieldCodec.ForBool(100), true, "FixedBool"),
             new FieldCodecTestData<string>(FieldCodec.ForString(100), "sample", "String"),
             new FieldCodecTestData<ByteString>(FieldCodec.ForBytes(100), ByteString.CopyFrom(1, 2, 3), "Bytes"),
             new FieldCodecTestData<int>(FieldCodec.ForInt32(100), -1000, "Int32"),
@@ -56,8 +56,8 @@ namespace Google.Protobuf
             new FieldCodecTestData<long>(FieldCodec.ForSFixed64(100), -1000, "SFixed64"),
             new FieldCodecTestData<ulong>(FieldCodec.ForUInt64(100), 1234, "UInt64"),
             new FieldCodecTestData<ulong>(FieldCodec.ForFixed64(100), 1234, "Fixed64"),
-            new FieldCodecTestData<float>(FieldCodec.ForFloat(100), 1234.5f, "Float"),
-            new FieldCodecTestData<double>(FieldCodec.ForDouble(100), 1234567890.5d, "Double"),
+            new FieldCodecTestData<float>(FieldCodec.ForFloat(100), 1234.5f, "FixedFloat"),
+            new FieldCodecTestData<double>(FieldCodec.ForDouble(100), 1234567890.5d, "FixedDouble"),
             new FieldCodecTestData<ForeignEnum>(
                 FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.ForeignBaz, "Enum"),
             new FieldCodecTestData<ForeignMessage>(

+ 3 - 3
csharp/src/Google.Protobuf.Test/FieldCodecTest.cs

@@ -43,7 +43,7 @@ namespace Google.Protobuf
 #pragma warning disable 0414 // Used by tests via reflection - do not remove!
         private static readonly List<ICodecTestData> Codecs = new List<ICodecTestData>
         {
-            new FieldCodecTestData<bool>(FieldCodec.ForBool(100), true, "Bool"),
+            new FieldCodecTestData<bool>(FieldCodec.ForBool(100), true, "FixedBool"),
             new FieldCodecTestData<string>(FieldCodec.ForString(100), "sample", "String"),
             new FieldCodecTestData<ByteString>(FieldCodec.ForBytes(100), ByteString.CopyFrom(1, 2, 3), "Bytes"),
             new FieldCodecTestData<int>(FieldCodec.ForInt32(100), -1000, "Int32"),
@@ -56,8 +56,8 @@ namespace Google.Protobuf
             new FieldCodecTestData<long>(FieldCodec.ForSFixed64(100), -1000, "SFixed64"),
             new FieldCodecTestData<ulong>(FieldCodec.ForUInt64(100), 1234, "UInt64"),
             new FieldCodecTestData<ulong>(FieldCodec.ForFixed64(100), 1234, "Fixed64"),
-            new FieldCodecTestData<float>(FieldCodec.ForFloat(100), 1234.5f, "Float"),
-            new FieldCodecTestData<double>(FieldCodec.ForDouble(100), 1234567890.5d, "Double"),
+            new FieldCodecTestData<float>(FieldCodec.ForFloat(100), 1234.5f, "FixedFloat"),
+            new FieldCodecTestData<double>(FieldCodec.ForDouble(100), 1234567890.5d, "FixedDouble"),
             new FieldCodecTestData<ForeignEnum>(
                 FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.ForeignBaz, "Enum"),
             new FieldCodecTestData<ForeignMessage>(

+ 7 - 3
csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs

@@ -42,13 +42,17 @@ namespace Google.Protobuf
         private const int LittleEndian64Size = 8;
         private const int LittleEndian32Size = 4;        
 
+        internal const int DoubleSize = LittleEndian64Size;
+        internal const int FloatSize = LittleEndian32Size;
+        internal const int BoolSize = 1;
+
         /// <summary>
         /// Computes the number of bytes that would be needed to encode a
         /// double field, including the tag.
         /// </summary>
         public static int ComputeDoubleSize(double value)
         {
-            return LittleEndian64Size;
+            return DoubleSize;
         }
 
         /// <summary>
@@ -57,7 +61,7 @@ namespace Google.Protobuf
         /// </summary>
         public static int ComputeFloatSize(float value)
         {
-            return LittleEndian32Size;
+            return FloatSize;
         }
 
         /// <summary>
@@ -119,7 +123,7 @@ namespace Google.Protobuf
         /// </summary>
         public static int ComputeBoolSize(bool value)
         {
-            return 1;
+            return BoolSize;
         }
 
         /// <summary>

+ 3 - 3
csharp/src/Google.Protobuf/FieldCodec.cs

@@ -72,7 +72,7 @@ namespace Google.Protobuf
         /// <returns>A codec for the given tag.</returns>
         public static FieldCodec<bool> ForBool(uint tag)
         {
-            return new FieldCodec<bool>(input => input.ReadBool(), (output, value) => output.WriteBool(value), CodedOutputStream.ComputeBoolSize, tag);
+            return new FieldCodec<bool>(input => input.ReadBool(), (output, value) => output.WriteBool(value), CodedOutputStream.BoolSize, tag);
         }
 
         /// <summary>
@@ -182,7 +182,7 @@ namespace Google.Protobuf
         /// <returns>A codec for the given tag.</returns>
         public static FieldCodec<float> ForFloat(uint tag)
         {
-            return new FieldCodec<float>(input => input.ReadFloat(), (output, value) => output.WriteFloat(value), CodedOutputStream.ComputeFloatSize, tag);
+            return new FieldCodec<float>(input => input.ReadFloat(), (output, value) => output.WriteFloat(value), CodedOutputStream.FloatSize, tag);
         }
 
         /// <summary>
@@ -192,7 +192,7 @@ namespace Google.Protobuf
         /// <returns>A codec for the given tag.</returns>
         public static FieldCodec<double> ForDouble(uint tag)
         {
-            return new FieldCodec<double>(input => input.ReadDouble(), (output, value) => output.WriteDouble(value), CodedOutputStream.ComputeDoubleSize, tag);
+            return new FieldCodec<double>(input => input.ReadDouble(), (output, value) => output.WriteDouble(value), CodedOutputStream.DoubleSize, tag);
         }
 
         // Enums are tricky. We can probably use expression trees to build these delegates automatically,