Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 8bb9cea

Browse files
committed
Faster CopyFromAscii
1 parent 17d282b commit 8bb9cea

File tree

1 file changed

+90
-39
lines changed

1 file changed

+90
-39
lines changed

src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPoolIterator2.cs

Lines changed: 90 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -636,68 +636,119 @@ public unsafe void CopyFrom(byte[] data, int offset, int count)
636636

637637
public unsafe void CopyFromAscii(string data)
638638
{
639-
Debug.Assert(_block != null);
640-
Debug.Assert(_block.Pool != null);
641-
Debug.Assert(_block.Next == null);
642-
Debug.Assert(_block.End == _index);
643-
644-
var pool = _block.Pool;
645639
var block = _block;
646640
var blockIndex = _index;
647-
var length = data.Length;
641+
var count = data.Length;
648642

649-
var bytesLeftInBlock = block.BlockEndOffset - blockIndex;
650-
var bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3;
643+
var blockRemaining = block.BlockEndOffset - blockIndex;
651644

652645
fixed (char* pData = data)
653646
{
654-
var input = pData;
655-
var inputEnd = pData + length;
656-
var inputEndMinusSpan = inputEnd - 3;
647+
if (blockRemaining >= count)
648+
{
649+
_index = blockIndex + count;
650+
651+
fixed (byte* output = block.Array)
652+
{
653+
CopyFromAscii(pData, output + blockIndex, count);
654+
}
657655

658-
while (input < inputEnd)
656+
block.End = _index;
657+
return;
658+
}
659+
660+
var input = pData;
661+
do
659662
{
660-
if (bytesLeftInBlock == 0)
663+
if (blockRemaining == 0)
661664
{
662-
var nextBlock = pool.Lease();
663-
block.End = blockIndex;
665+
var nextBlock = block.Pool.Lease();
666+
blockIndex = nextBlock.Data.Offset;
667+
blockRemaining = nextBlock.Data.Count;
664668
block.Next = nextBlock;
665669
block = nextBlock;
666-
667-
blockIndex = block.Data.Offset;
668-
bytesLeftInBlock = block.Data.Count;
669-
bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3;
670670
}
671671

672-
fixed (byte* pOutput = block.Data.Array)
672+
if (count > blockRemaining)
673673
{
674-
var output = pOutput + block.End;
674+
count -= blockRemaining;
675675

676-
var copied = 0;
677-
for (; input < inputEndMinusSpan && copied < bytesLeftInBlockMinusSpan; copied += 4)
676+
fixed (byte* output = block.Array)
678677
{
679-
*(output) = (byte)*(input);
680-
*(output + 1) = (byte)*(input + 1);
681-
*(output + 2) = (byte)*(input + 2);
682-
*(output + 3) = (byte)*(input + 3);
683-
output += 4;
684-
input += 4;
678+
CopyFromAscii(input, output + blockIndex, blockRemaining);
685679
}
686-
for (; input < inputEnd && copied < bytesLeftInBlock; copied++)
680+
681+
block.End = blockIndex + blockRemaining;
682+
input += blockRemaining;
683+
blockRemaining = 0;
684+
continue;
685+
}
686+
else
687+
{
688+
_index = blockIndex + count;
689+
690+
fixed (byte* output = block.Array)
687691
{
688-
*(output++) = (byte)*(input++);
692+
CopyFromAscii(input, output + blockIndex, count);
689693
}
690694

691-
blockIndex += copied;
692-
bytesLeftInBlockMinusSpan -= copied;
693-
bytesLeftInBlock -= copied;
695+
block.End = _index;
696+
_block = block;
697+
return;
694698
}
695-
}
699+
} while (true);
696700
}
701+
}
697702

698-
block.End = blockIndex;
699-
_block = block;
700-
_index = blockIndex;
703+
private unsafe static void CopyFromAscii(char* input, byte* output, int count)
704+
{
705+
var i = 0;
706+
707+
while (i + 11 < count)
708+
{
709+
i += 12;
710+
*(output) = (byte)*(input);
711+
*(output + 1) = (byte)*(input + 1);
712+
*(output + 2) = (byte)*(input + 2);
713+
*(output + 3) = (byte)*(input + 3);
714+
*(output + 4) = (byte)*(input + 4);
715+
*(output + 5) = (byte)*(input + 5);
716+
*(output + 6) = (byte)*(input + 6);
717+
*(output + 7) = (byte)*(input + 7);
718+
*(output + 8) = (byte)*(input + 8);
719+
*(output + 9) = (byte)*(input + 9);
720+
*(output + 10) = (byte)*(input + 10);
721+
*(output + 11) = (byte)*(input + 11);
722+
output += 12;
723+
input += 12;
724+
}
725+
if (i + 6 < count)
726+
{
727+
i += 6;
728+
*(output) = (byte)*(input);
729+
*(output + 1) = (byte)*(input + 1);
730+
*(output + 2) = (byte)*(input + 2);
731+
*(output + 3) = (byte)*(input + 3);
732+
*(output + 4) = (byte)*(input + 4);
733+
*(output + 5) = (byte)*(input + 5);
734+
output += 6;
735+
input += 6;
736+
}
737+
if (i + 3 < count)
738+
{
739+
i += 4;
740+
*(output) = (byte)*(input);
741+
*(output + 1) = (byte)*(input + 1);
742+
*(output + 2) = (byte)*(input + 2);
743+
*(output + 3) = (byte)*(input + 3);
744+
output += 4;
745+
input += 4;
746+
}
747+
while (i < count)
748+
{
749+
i++;
750+
*(output++) = (byte)*(input++);
751+
}
701752
}
702753
}
703754
}

0 commit comments

Comments
 (0)