optimize WriteFloat

pull/7576/head
Jan Tattermusch 5 years ago
parent 886c263a3c
commit a296413b5a
  1. 37
      csharp/src/Google.Protobuf/WritingPrimitives.cs

@ -32,6 +32,7 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security; using System.Security;
using System.Text; using System.Text;
@ -61,25 +62,35 @@ namespace Google.Protobuf
/// Writes a float field value, without a tag, to the stream. /// Writes a float field value, without a tag, to the stream.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteFloat(ref Span<byte> buffer, ref WriterInternalState state, float value) public static unsafe void WriteFloat(ref Span<byte> buffer, ref WriterInternalState state, float value)
{ {
// TODO: avoid allocating a byte array!!! const int length = sizeof(float);
byte[] rawBytes = BitConverter.GetBytes(value); if (state.limit - state.position >= length)
if (!BitConverter.IsLittleEndian)
{ {
ByteArray.Reverse(rawBytes); // if there's enough space in the buffer, write the float directly into the buffer
} var floatSpan = buffer.Slice(state.position, length);
Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value);
if (state.limit - state.position >= 4) if (!BitConverter.IsLittleEndian)
{ {
buffer[state.position++] = rawBytes[0]; floatSpan.Reverse();
buffer[state.position++] = rawBytes[1]; }
buffer[state.position++] = rawBytes[2]; state.position += length;
buffer[state.position++] = rawBytes[3];
} }
else else
{ {
WriteRawBytes(ref buffer, ref state, rawBytes, 0, 4); 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]);
} }
} }

Loading…
Cancel
Save