Skip to content

Commit 4f0afc7

Browse files
committed
optimize WriteRawTag
1 parent 2f16981 commit 4f0afc7

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

csharp/src/Google.Protobuf/WritingPrimitives.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,20 @@ public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState st
504504
/// Writes the given two-byte tag directly to the stream.
505505
/// </summary>
506506
public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2)
507+
{
508+
if (state.position + 2 > buffer.Length)
509+
{
510+
WriteRawTagSlowPath(ref buffer, ref state, b1, b2);
511+
}
512+
else
513+
{
514+
buffer[state.position++] = b1;
515+
buffer[state.position++] = b2;
516+
}
517+
}
518+
519+
[MethodImpl(MethodImplOptions.NoInlining)]
520+
private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2)
507521
{
508522
WriteRawByte(ref buffer, ref state, b1);
509523
WriteRawByte(ref buffer, ref state, b2);
@@ -513,6 +527,21 @@ public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState st
513527
/// Writes the given three-byte tag directly to the stream.
514528
/// </summary>
515529
public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3)
530+
{
531+
if (state.position + 3 > buffer.Length)
532+
{
533+
WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3);
534+
}
535+
else
536+
{
537+
buffer[state.position++] = b1;
538+
buffer[state.position++] = b2;
539+
buffer[state.position++] = b3;
540+
}
541+
}
542+
543+
[MethodImpl(MethodImplOptions.NoInlining)]
544+
private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3)
516545
{
517546
WriteRawByte(ref buffer, ref state, b1);
518547
WriteRawByte(ref buffer, ref state, b2);
@@ -523,6 +552,23 @@ public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState st
523552
/// Writes the given four-byte tag directly to the stream.
524553
/// </summary>
525554
public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4)
555+
{
556+
if (state.position + 4 > buffer.Length)
557+
{
558+
WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4);
559+
}
560+
else
561+
{
562+
buffer[state.position++] = b1;
563+
buffer[state.position++] = b2;
564+
buffer[state.position++] = b3;
565+
buffer[state.position++] = b4;
566+
}
567+
}
568+
569+
[MethodImpl(MethodImplOptions.NoInlining)]
570+
571+
private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4)
526572
{
527573
WriteRawByte(ref buffer, ref state, b1);
528574
WriteRawByte(ref buffer, ref state, b2);
@@ -534,6 +580,23 @@ public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState st
534580
/// Writes the given five-byte tag directly to the stream.
535581
/// </summary>
536582
public static void WriteRawTag(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5)
583+
{
584+
if (state.position + 5 > buffer.Length)
585+
{
586+
WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4, b5);
587+
}
588+
else
589+
{
590+
buffer[state.position++] = b1;
591+
buffer[state.position++] = b2;
592+
buffer[state.position++] = b3;
593+
buffer[state.position++] = b4;
594+
buffer[state.position++] = b5;
595+
}
596+
}
597+
598+
[MethodImpl(MethodImplOptions.NoInlining)]
599+
private static void WriteRawTagSlowPath(ref Span<byte> buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5)
537600
{
538601
WriteRawByte(ref buffer, ref state, b1);
539602
WriteRawByte(ref buffer, ref state, b2);

0 commit comments

Comments
 (0)