From 4f0afc78528416b00ef2b7007a520f668ceea343 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 23 Jun 2020 20:17:33 +0200 Subject: [PATCH] optimize WriteRawTag --- .../src/Google.Protobuf/WritingPrimitives.cs | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/csharp/src/Google.Protobuf/WritingPrimitives.cs b/csharp/src/Google.Protobuf/WritingPrimitives.cs index 4323691bad..4ccad7376d 100644 --- a/csharp/src/Google.Protobuf/WritingPrimitives.cs +++ b/csharp/src/Google.Protobuf/WritingPrimitives.cs @@ -504,6 +504,20 @@ namespace Google.Protobuf /// Writes the given two-byte tag directly to the stream. /// public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2) + { + if (state.position + 2 > buffer.Length) + { + WriteRawTagSlowPath(ref buffer, ref state, b1, b2); + } + else + { + buffer[state.position++] = b1; + buffer[state.position++] = b2; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); @@ -513,6 +527,21 @@ namespace Google.Protobuf /// Writes the given three-byte tag directly to the stream. /// public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3) + { + if (state.position + 3 > buffer.Length) + { + WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3); + } + else + { + buffer[state.position++] = b1; + buffer[state.position++] = b2; + buffer[state.position++] = b3; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); @@ -523,6 +552,23 @@ namespace Google.Protobuf /// Writes the given four-byte tag directly to the stream. /// public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4) + { + if (state.position + 4 > buffer.Length) + { + WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4); + } + else + { + buffer[state.position++] = b1; + buffer[state.position++] = b2; + buffer[state.position++] = b3; + buffer[state.position++] = b4; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + + private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2); @@ -534,6 +580,23 @@ namespace Google.Protobuf /// Writes the given five-byte tag directly to the stream. /// public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5) + { + if (state.position + 5 > buffer.Length) + { + WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4, b5); + } + else + { + buffer[state.position++] = b1; + buffer[state.position++] = b2; + buffer[state.position++] = b3; + buffer[state.position++] = b4; + buffer[state.position++] = b5; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5) { WriteRawByte(ref buffer, ref state, b1); WriteRawByte(ref buffer, ref state, b2);