Skip to content

Commit 41e3cce

Browse files
fix: use recyclable streams for serialization to reduce memory pressure and improve overall performance
* Updated serialization writers to use RecyclableMemoryStream * Updated to use private static manager * Updated to use IBufferWriter<byte> as per PR review comments * Update src/serialization/json/JsonSerializationWriter.cs Co-authored-by: Vincent Biret <vincentbiret@hotmail.com> * Update src/serialization/json/JsonSerializationWriter.cs Co-authored-by: Vincent Biret <vincentbiret@hotmail.com> --------- Co-authored-by: Vincent Biret <vincentbiret@hotmail.com>
1 parent cdb40cc commit 41e3cce

8 files changed

Lines changed: 25 additions & 5 deletions

src/serialization/form/FormSerializationWriter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@
1212
using System;
1313
using System.Collections.Generic;
1414
using Microsoft.Kiota.Abstractions.Helpers;
15+
using Microsoft.IO;
1516

1617
namespace Microsoft.Kiota.Serialization.Form;
1718
/// <summary>Represents a serialization writer that can be used to write a form url encoded string.</summary>
1819
public class FormSerializationWriter : ISerializationWriter
1920
{
2021
private int depth;
2122
private readonly StringBuilder _builder = new();
23+
private static readonly RecyclableMemoryStreamManager _memoryStreamManager = new RecyclableMemoryStreamManager();
2224
/// <inheritdoc/>
2325
public Action<IParsable>? OnBeforeObjectSerialization { get; set; }
2426
/// <inheritdoc/>
@@ -31,7 +33,7 @@ public void Dispose()
3133
GC.SuppressFinalize(this);
3234
}
3335
/// <inheritdoc/>
34-
public Stream GetSerializedContent() => new MemoryStream(Encoding.UTF8.GetBytes(_builder.ToString()));
36+
public Stream GetSerializedContent() => _memoryStreamManager.GetStream(Encoding.UTF8.GetBytes(_builder.ToString()));
3537
/// <inheritdoc/>
3638
public void WriteAdditionalData(IDictionary<string, object> value)
3739
{

src/serialization/form/Microsoft.Kiota.Serialization.Form.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
</ItemGroup>
1515

1616
<ItemGroup>
17+
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
1718
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15">
1819
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1920
<PrivateAssets>all</PrivateAssets>

src/serialization/json/JsonSerializationWriter.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Text;
1111
using System.Text.Json;
1212
using System.Xml;
13+
using Microsoft.IO;
1314
using Microsoft.Kiota.Abstractions;
1415
using Microsoft.Kiota.Abstractions.Helpers;
1516
using Microsoft.Kiota.Abstractions.Serialization;
@@ -18,14 +19,19 @@
1819
using System.Diagnostics.CodeAnalysis;
1920
#endif
2021

22+
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_0_OR_GREATER
23+
using System.Buffers;
24+
#endif
25+
2126
namespace Microsoft.Kiota.Serialization.Json
2227
{
2328
/// <summary>
2429
/// The <see cref="ISerializationWriter"/> implementation for json content types.
2530
/// </summary>
2631
public class JsonSerializationWriter : ISerializationWriter, IDisposable
2732
{
28-
private readonly MemoryStream _stream = new MemoryStream();
33+
private static readonly RecyclableMemoryStreamManager _memoryStreamManager = new RecyclableMemoryStreamManager();
34+
private readonly RecyclableMemoryStream _stream = _memoryStreamManager.GetStream();
2935
private readonly KiotaJsonSerializationContext _kiotaJsonSerializationContext;
3036

3137
/// <summary>
@@ -48,7 +54,11 @@ public JsonSerializationWriter()
4854
public JsonSerializationWriter(KiotaJsonSerializationContext kiotaJsonSerializationContext)
4955
{
5056
_kiotaJsonSerializationContext = kiotaJsonSerializationContext;
51-
writer = new Utf8JsonWriter(_stream, new JsonWriterOptions
57+
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER
58+
writer = new Utf8JsonWriter((IBufferWriter<byte>)_stream, new JsonWriterOptions
59+
#else
60+
writer = new Utf8JsonWriter((Stream)_stream, new JsonWriterOptions
61+
#endif
5262
{
5363
Encoder = kiotaJsonSerializationContext.Options.Encoder,
5464
Indented = kiotaJsonSerializationContext.Options.WriteIndented

src/serialization/json/Microsoft.Kiota.Serialization.Json.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
</ItemGroup>
2222

2323
<ItemGroup>
24+
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
2425
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15">
2526
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2627
<PrivateAssets>all</PrivateAssets>

src/serialization/multipart/Microsoft.Kiota.Serialization.Multipart.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
</ItemGroup>
1515

1616
<ItemGroup>
17+
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
1718
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15">
1819
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1920
<PrivateAssets>all</PrivateAssets>

src/serialization/multipart/MultipartSerializationWriter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Collections.Generic;
77
using System.IO;
8+
using Microsoft.IO;
89
using Microsoft.Kiota.Abstractions;
910
using Microsoft.Kiota.Abstractions.Serialization;
1011
#if NET5_0_OR_GREATER
@@ -17,7 +18,8 @@ namespace Microsoft.Kiota.Serialization.Multipart;
1718
/// </summary>
1819
public class MultipartSerializationWriter : ISerializationWriter
1920
{
20-
private readonly MemoryStream _stream = new MemoryStream();
21+
private static readonly RecyclableMemoryStreamManager _memoryStreamManager = new RecyclableMemoryStreamManager();
22+
private readonly RecyclableMemoryStream _stream = _memoryStreamManager.GetStream();
2123
/// <inheritdoc/>
2224
public Action<IParsable>? OnBeforeObjectSerialization { get; set; }
2325
/// <inheritdoc/>

src/serialization/text/Microsoft.Kiota.Serialization.Text.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
</ItemGroup>
1515

1616
<ItemGroup>
17+
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
1718
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15">
1819
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1920
<PrivateAssets>all</PrivateAssets>

src/serialization/text/TextSerializationWriter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Globalization;
44
using System.IO;
55
using System.Xml;
6+
using Microsoft.IO;
67
using Microsoft.Kiota.Abstractions;
78
using Microsoft.Kiota.Abstractions.Extensions;
89
using Microsoft.Kiota.Abstractions.Helpers;
@@ -19,7 +20,8 @@ namespace Microsoft.Kiota.Serialization.Text;
1920
/// </summary>
2021
public class TextSerializationWriter : ISerializationWriter, IDisposable
2122
{
22-
private readonly MemoryStream _stream = new MemoryStream();
23+
private static readonly RecyclableMemoryStreamManager _memoryStreamManager = new RecyclableMemoryStreamManager();
24+
private readonly RecyclableMemoryStream _stream = _memoryStreamManager.GetStream();
2325
private readonly StreamWriter _writer;
2426
/// <summary>
2527
/// Initializes a new instance of the <see cref="TextSerializationWriter"/> class.

0 commit comments

Comments
 (0)