Skip to content

Commit ebe3eef

Browse files
Copilotstephentoub
andcommitted
Apply performance optimizations using MemoryMarshal.TryGetArray
Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
1 parent e405dfc commit ebe3eef

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

src/ModelContextProtocol.Core/Protocol/BlobResourceContents.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Runtime.InteropServices;
12
using System.Text.Json.Serialization;
23

34
namespace ModelContextProtocol.Protocol;
@@ -56,10 +57,11 @@ public ReadOnlyMemory<byte> Data
5657
{
5758
if (_decodedData is null)
5859
{
59-
#if NET6_0_OR_GREATER
60+
#if NET
6061
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Blob.Span));
6162
#else
62-
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Blob.ToArray()));
63+
byte[] array = MemoryMarshal.TryGetArray(Blob, out ArraySegment<byte> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length ? segment.Array : Blob.ToArray();
64+
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(array));
6365
#endif
6466
}
6567
return _decodedData;

src/ModelContextProtocol.Core/Protocol/ContentBlock.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.ComponentModel;
33
using System.Diagnostics;
44
using System.Diagnostics.CodeAnalysis;
5+
using System.Runtime.InteropServices;
56
using System.Text.Json;
67
using System.Text.Json.Nodes;
78
using System.Text.Json.Serialization;
@@ -419,10 +420,11 @@ public ReadOnlyMemory<byte> DecodedData
419420
{
420421
if (_decodedData is null)
421422
{
422-
#if NET6_0_OR_GREATER
423+
#if NET
423424
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Data.Span));
424425
#else
425-
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Data.ToArray()));
426+
byte[] array = MemoryMarshal.TryGetArray(Data, out ArraySegment<byte> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length ? segment.Array : Data.ToArray();
427+
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(array));
426428
#endif
427429
}
428430
return _decodedData;
@@ -479,10 +481,11 @@ public ReadOnlyMemory<byte> DecodedData
479481
{
480482
if (_decodedData is null)
481483
{
482-
#if NET6_0_OR_GREATER
484+
#if NET
483485
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Data.Span));
484486
#else
485-
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(Data.ToArray()));
487+
byte[] array = MemoryMarshal.TryGetArray(Data, out ArraySegment<byte> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length ? segment.Array : Data.ToArray();
488+
_decodedData = Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(array));
486489
#endif
487490
}
488491
return _decodedData;

src/ModelContextProtocol.Core/Server/AIFunctionMcpServerResource.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Globalization;
88
using System.Reflection;
99
using System.Runtime.CompilerServices;
10+
using System.Runtime.InteropServices;
1011
using System.Text;
1112
using System.Text.Json;
1213
using System.Text.Json.Nodes;
@@ -391,7 +392,14 @@ public override async ValueTask<ReadResourceResult> ReadAsync(
391392

392393
DataContent dc => new()
393394
{
394-
Contents = [new BlobResourceContents { Uri = request.Params!.Uri, MimeType = dc.MediaType, Blob = System.Text.Encoding.UTF8.GetBytes(dc.Base64Data.ToString()) }],
395+
Contents = [new BlobResourceContents
396+
{
397+
Uri = request.Params!.Uri,
398+
MimeType = dc.MediaType,
399+
Blob = MemoryMarshal.TryGetArray(dc.Base64Data, out ArraySegment<char> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length
400+
? System.Text.Encoding.UTF8.GetBytes(segment.Array)
401+
: System.Text.Encoding.UTF8.GetBytes(dc.Base64Data.ToString())
402+
}],
395403
},
396404

397405
string text => new()
@@ -420,7 +428,9 @@ public override async ValueTask<ReadResourceResult> ReadAsync(
420428
{
421429
Uri = request.Params!.Uri,
422430
MimeType = dc.MediaType,
423-
Blob = System.Text.Encoding.UTF8.GetBytes(dc.Base64Data.ToString())
431+
Blob = MemoryMarshal.TryGetArray(dc.Base64Data, out ArraySegment<char> segment) && segment.Offset == 0 && segment.Count == segment.Array!.Length
432+
? System.Text.Encoding.UTF8.GetBytes(segment.Array)
433+
: System.Text.Encoding.UTF8.GetBytes(dc.Base64Data.ToString())
424434
},
425435

426436
_ => throw new InvalidOperationException($"Unsupported AIContent type '{ac.GetType()}' returned from resource function."),

0 commit comments

Comments
 (0)