From b111c91cb0c6e165b8e002dcbef500bd7c908afc Mon Sep 17 00:00:00 2001 From: David Fowler Date: Thu, 22 Mar 2018 08:47:06 -0700 Subject: [PATCH] Don't copy the array for incoming msgpack reads (#1686) * Don't copy the array for incoming msgpack reads - Don't use ToArray on the already sliced msgpack data. - Turns out msgpack is self describing enough to not require the count, it just needs the buffer and start offset. --- .../Internal/Protocol/MessagePackHubProtocol.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs index 046df1cad1..8b01cbd3e3 100644 --- a/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs @@ -3,8 +3,10 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Runtime.ExceptionServices; +using System.Runtime.InteropServices; using Microsoft.AspNetCore.Protocols; using Microsoft.AspNetCore.SignalR.Internal.Formatters; using Microsoft.AspNetCore.Sockets; @@ -41,15 +43,18 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol { while (BinaryMessageParser.TryParseMessage(ref input, out var payload)) { - messages.Add(ParseMessage(payload.ToArray(), binder)); + var isArray = MemoryMarshal.TryGetArray(payload, out var arraySegment); + // This will never be false unless we started using un-managed buffers + Debug.Assert(isArray); + messages.Add(ParseMessage(arraySegment.Array, arraySegment.Offset, binder)); } return messages.Count > 0; } - private static HubMessage ParseMessage(byte[] input, IInvocationBinder binder) + private static HubMessage ParseMessage(byte[] input, int startOffset, IInvocationBinder binder) { - using (var unpacker = Unpacker.Create(input)) + using (var unpacker = Unpacker.Create(input, startOffset)) { _ = ReadArrayLength(unpacker, "elementCount");