optimize WriteFixed32 and WriteFixed64

pull/7576/head
Jan Tattermusch 5 years ago
parent 17a4b181a0
commit 6afd469fe0
  1. 40
      csharp/src/Google.Protobuf/WritingPrimitives.cs

@ -340,12 +340,9 @@ namespace Google.Protobuf
public static void WriteRawLittleEndian32(ref Span<byte> buffer, ref WriterInternalState state, uint value) public static void WriteRawLittleEndian32(ref Span<byte> buffer, ref WriterInternalState state, uint value)
{ {
const int length = sizeof(uint); const int length = sizeof(uint);
if (state.position + length > state.limit) if (state.position + length > buffer.Length)
{ {
WriteRawByte(ref buffer, ref state, (byte)value); WriteRawLittleEndian32SlowPath(ref buffer, ref state, value);
WriteRawByte(ref buffer, ref state, (byte)(value >> 8));
WriteRawByte(ref buffer, ref state, (byte)(value >> 16));
WriteRawByte(ref buffer, ref state, (byte)(value >> 24));
} }
else else
{ {
@ -354,19 +351,21 @@ namespace Google.Protobuf
} }
} }
[MethodImpl(MethodImplOptions.NoInlining)]
private static void WriteRawLittleEndian32SlowPath(ref Span<byte> buffer, ref WriterInternalState state, uint value)
{
WriteRawByte(ref buffer, ref state, (byte)value);
WriteRawByte(ref buffer, ref state, (byte)(value >> 8));
WriteRawByte(ref buffer, ref state, (byte)(value >> 16));
WriteRawByte(ref buffer, ref state, (byte)(value >> 24));
}
public static void WriteRawLittleEndian64(ref Span<byte> buffer, ref WriterInternalState state, ulong value) public static void WriteRawLittleEndian64(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
{ {
const int length = sizeof(ulong); const int length = sizeof(ulong);
if (state.position + length > state.limit) if (state.position + length > buffer.Length)
{ {
WriteRawByte(ref buffer, ref state, (byte)value); WriteRawLittleEndian64SlowPath(ref buffer, ref state, value);
WriteRawByte(ref buffer, ref state, (byte)(value >> 8));
WriteRawByte(ref buffer, ref state, (byte)(value >> 16));
WriteRawByte(ref buffer, ref state, (byte)(value >> 24));
WriteRawByte(ref buffer, ref state, (byte)(value >> 32));
WriteRawByte(ref buffer, ref state, (byte)(value >> 40));
WriteRawByte(ref buffer, ref state, (byte)(value >> 48));
WriteRawByte(ref buffer, ref state, (byte)(value >> 56));
} }
else else
{ {
@ -385,6 +384,19 @@ namespace Google.Protobuf
} }
} }
[MethodImpl(MethodImplOptions.NoInlining)]
public static void WriteRawLittleEndian64SlowPath(ref Span<byte> buffer, ref WriterInternalState state, ulong value)
{
WriteRawByte(ref buffer, ref state, (byte)value);
WriteRawByte(ref buffer, ref state, (byte)(value >> 8));
WriteRawByte(ref buffer, ref state, (byte)(value >> 16));
WriteRawByte(ref buffer, ref state, (byte)(value >> 24));
WriteRawByte(ref buffer, ref state, (byte)(value >> 32));
WriteRawByte(ref buffer, ref state, (byte)(value >> 40));
WriteRawByte(ref buffer, ref state, (byte)(value >> 48));
WriteRawByte(ref buffer, ref state, (byte)(value >> 56));
}
public static void WriteRawByte(ref Span<byte> buffer, ref WriterInternalState state, byte value) public static void WriteRawByte(ref Span<byte> buffer, ref WriterInternalState state, byte value)
{ {
if (state.position == state.limit) if (state.position == state.limit)

Loading…
Cancel
Save