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

Commit f858a10

Browse files
committed
Faster CopyFrom
1 parent ada61f8 commit f858a10

File tree

3 files changed

+34
-29
lines changed

3 files changed

+34
-29
lines changed

src/Microsoft.AspNet.Server.Kestrel/Http/SocketOutput.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public Task WriteAsync(
8787
if (buffer.Count > 0)
8888
{
8989
var tail = ProducingStart();
90-
tail.CopyFrom(buffer);
90+
tail.CopyFrom(buffer.Array, buffer.Offset, buffer.Count);
9191
// We do our own accounting below
9292
ProducingCompleteNoPreComplete(tail);
9393
}

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

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -589,47 +589,52 @@ public void CopyFrom(ArraySegment<byte> buffer)
589589
CopyFrom(buffer.Array, buffer.Offset, buffer.Count);
590590
}
591591

592-
public void CopyFrom(byte[] data, int offset, int count)
592+
public unsafe void CopyFrom(byte[] data, int offset, int count)
593593
{
594-
Debug.Assert(_block != null);
595-
Debug.Assert(_block.Pool != null);
596-
Debug.Assert(_block.Next == null);
597-
Debug.Assert(_block.End == _index);
598-
599-
var pool = _block.Pool;
600594
var block = _block;
601595
var blockIndex = _index;
602-
603-
var bufferIndex = offset;
604-
var remaining = count;
605596
var bytesLeftInBlock = block.Data.Offset + block.Data.Count - blockIndex;
606597

607-
while (remaining > 0)
598+
if (bytesLeftInBlock >= count)
599+
{
600+
_index = blockIndex + count;
601+
Buffer.BlockCopy(data, offset, block.Array, blockIndex, count);
602+
block.End = _index;
603+
return;
604+
}
605+
606+
var pool = block.Pool;
607+
608+
while (count > 0)
608609
{
609610
if (bytesLeftInBlock == 0)
610611
{
611-
var nextBlock = pool.Lease();
612612
block.End = blockIndex;
613+
614+
var nextBlock = pool.Lease();
615+
blockIndex = nextBlock.Data.Offset;
616+
bytesLeftInBlock = nextBlock.Data.Count;
613617
block.Next = nextBlock;
614618
block = nextBlock;
615-
616-
blockIndex = block.Data.Offset;
617-
bytesLeftInBlock = block.Data.Count;
618619
}
619620

620-
var bytesToCopy = remaining < bytesLeftInBlock ? remaining : bytesLeftInBlock;
621-
622-
Buffer.BlockCopy(data, bufferIndex, block.Array, blockIndex, bytesToCopy);
623-
624-
blockIndex += bytesToCopy;
625-
bufferIndex += bytesToCopy;
626-
remaining -= bytesToCopy;
627-
bytesLeftInBlock -= bytesToCopy;
621+
if (count > bytesLeftInBlock)
622+
{
623+
count -= bytesLeftInBlock;
624+
Buffer.BlockCopy(data, offset, block.Array, blockIndex, bytesLeftInBlock);
625+
blockIndex += bytesLeftInBlock;
626+
offset += bytesLeftInBlock;
627+
bytesLeftInBlock = 0;
628+
}
629+
else
630+
{
631+
_index = blockIndex + count;
632+
Buffer.BlockCopy(data, offset, block.Array, blockIndex, count);
633+
block.End = _index;
634+
_block = block;
635+
return;
636+
}
628637
}
629-
630-
block.End = blockIndex;
631-
_block = block;
632-
_index = blockIndex;
633638
}
634639

635640
public unsafe void CopyFromAscii(string data)

test/Microsoft.AspNet.Server.KestrelTests/MemoryPoolBlock2Tests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ public void CopyFromCorrectlyTraversesBlocks()
245245

246246
Assert.Null(block1.Next);
247247

248-
end.CopyFrom(new ArraySegment<byte>(buffer));
248+
end.CopyFrom(buffer, 0, buffer.Length);
249249

250250
Assert.NotNull(block1.Next);
251251

0 commit comments

Comments
 (0)