Przeglądaj źródła

WriteFloat improvements

Jan Tattermusch 5 lat temu
rodzic
commit
d3557cab21
1 zmienionych plików z 19 dodań i 11 usunięć
  1. 19 11
      csharp/src/Google.Protobuf/WritingPrimitives.cs

+ 19 - 11
csharp/src/Google.Protobuf/WritingPrimitives.cs

@@ -64,7 +64,7 @@ namespace Google.Protobuf
         public static unsafe void WriteFloat(ref Span<byte> buffer, ref WriterInternalState state, float value)
         {
             const int length = sizeof(float);
-            if (state.limit - state.position >= length)
+            if (buffer.Length - state.position >= length)
             {
                 // if there's enough space in the buffer, write the float directly into the buffer
                 var floatSpan = buffer.Slice(state.position, length);
@@ -78,19 +78,27 @@ namespace Google.Protobuf
             }
             else
             {
-                Span<byte> floatSpan = stackalloc byte[length];
-                Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value);
+                WriteFloatSlowPath(ref buffer, ref state, value);
+            }
+        }
 
-                if (!BitConverter.IsLittleEndian)
-                {
-                    floatSpan.Reverse();
-                }
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        private static unsafe void WriteFloatSlowPath(ref Span<byte> buffer, ref WriterInternalState state, float value)
+        {
+            const int length = sizeof(float);
 
-                WriteRawByte(ref buffer, ref state, floatSpan[0]);
-                WriteRawByte(ref buffer, ref state, floatSpan[1]);
-                WriteRawByte(ref buffer, ref state, floatSpan[2]);
-                WriteRawByte(ref buffer, ref state, floatSpan[3]);
+            // TODO(jtattermusch): deduplicate the code. Populating the span is the same as for the fastpath.
+            Span<byte> floatSpan = stackalloc byte[length];
+            Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value);
+            if (!BitConverter.IsLittleEndian)
+            {
+                floatSpan.Reverse();
             }
+
+            WriteRawByte(ref buffer, ref state, floatSpan[0]);
+            WriteRawByte(ref buffer, ref state, floatSpan[1]);
+            WriteRawByte(ref buffer, ref state, floatSpan[2]);
+            WriteRawByte(ref buffer, ref state, floatSpan[3]);
         }
 
         /// <summary>