Skip to content

Commit

Permalink
Use Utf8JsonWriterCache in JsonNode.To{Json}String (#92358)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephentoub authored Sep 20, 2023
1 parent c0b5150 commit 614d864
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Threading;

namespace System.Text.Json.Nodes
{
public abstract partial class JsonNode
Expand All @@ -12,8 +14,25 @@ public abstract partial class JsonNode
/// <returns>JSON representation of current instance.</returns>
public string ToJsonString(JsonSerializerOptions? options = null)
{
using PooledByteBufferWriter output = WriteToPooledBuffer(options, options?.GetWriterOptions() ?? default);
return JsonHelpers.Utf8GetString(output.WrittenMemory.Span);
JsonWriterOptions writerOptions = default;
int defaultBufferSize = JsonSerializerOptions.BufferSizeDefault;
if (options is not null)
{
writerOptions = options.GetWriterOptions();
defaultBufferSize = options.DefaultBufferSize;
}

Utf8JsonWriter writer = Utf8JsonWriterCache.RentWriterAndBuffer(writerOptions, defaultBufferSize, out PooledByteBufferWriter output);
try
{
WriteTo(writer, options);
writer.Flush();
return JsonHelpers.Utf8GetString(output.WrittenMemory.Span);
}
finally
{
Utf8JsonWriterCache.ReturnWriterAndBuffer(writer, output);
}
}

/// <summary>
Expand All @@ -37,8 +56,17 @@ public override string ToString()
}
}

using PooledByteBufferWriter output = WriteToPooledBuffer(writerOptions: new JsonWriterOptions { Indented = true });
return JsonHelpers.Utf8GetString(output.WrittenMemory.Span);
Utf8JsonWriter writer = Utf8JsonWriterCache.RentWriterAndBuffer(new JsonWriterOptions { Indented = true }, JsonSerializerOptions.BufferSizeDefault, out PooledByteBufferWriter output);
try
{
WriteTo(writer);
writer.Flush();
return JsonHelpers.Utf8GetString(output.WrittenMemory.Span);
}
finally
{
Utf8JsonWriterCache.ReturnWriterAndBuffer(writer, output);
}
}

/// <summary>
Expand All @@ -50,19 +78,5 @@ public override string ToString()
/// </exception>
/// <param name="options">Options to control the serialization behavior.</param>
public abstract void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null);

/// <summary>
/// Creates a pooled buffer writer instance and serializes all contents to it.
/// </summary>
internal PooledByteBufferWriter WriteToPooledBuffer(
JsonSerializerOptions? options = null,
JsonWriterOptions writerOptions = default,
int bufferSize = JsonSerializerOptions.BufferSizeDefault)
{
var bufferWriter = new PooledByteBufferWriter(bufferSize);
using var writer = new Utf8JsonWriter(bufferWriter, writerOptions);
WriteTo(writer, options);
return bufferWriter;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,17 @@ internal sealed override JsonValueKind GetValueKindCore()
return element.ValueKind;
}

using PooledByteBufferWriter output = WriteToPooledBuffer();
return JsonElement.ParseValue(output.WrittenMemory.Span, options: default).ValueKind;
Utf8JsonWriter writer = Utf8JsonWriterCache.RentWriterAndBuffer(default, JsonSerializerOptions.BufferSizeDefault, out PooledByteBufferWriter output);
try
{
WriteTo(writer);
writer.Flush();
return JsonElement.ParseValue(output.WrittenMemory.Span, options: default).ValueKind;
}
finally
{
Utf8JsonWriterCache.ReturnWriterAndBuffer(writer, output);
}
}

internal sealed override bool DeepEqualsCore(JsonNode? otherNode)
Expand Down Expand Up @@ -107,9 +116,21 @@ internal sealed override bool DeepEqualsCore(JsonNode? otherNode)
}
}

using PooledByteBufferWriter thisOutput = WriteToPooledBuffer();
using PooledByteBufferWriter otherOutput = otherNode.WriteToPooledBuffer();
using PooledByteBufferWriter thisOutput = WriteToPooledBuffer(this);
using PooledByteBufferWriter otherOutput = WriteToPooledBuffer(otherNode);
return thisOutput.WrittenMemory.Span.SequenceEqual(otherOutput.WrittenMemory.Span);

static PooledByteBufferWriter WriteToPooledBuffer(
JsonNode node,
JsonSerializerOptions? options = null,
JsonWriterOptions writerOptions = default,
int bufferSize = JsonSerializerOptions.BufferSizeDefault)
{
var bufferWriter = new PooledByteBufferWriter(bufferSize);
using var writer = new Utf8JsonWriter(bufferWriter, writerOptions);
node.WriteTo(writer, options);
return bufferWriter;
}
}

internal TypeToConvert ConvertJsonElement<TypeToConvert>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ internal static class Utf8JsonWriterCache
[ThreadStatic]
private static ThreadLocalState? t_threadLocalState;

public static Utf8JsonWriter RentWriterAndBuffer(JsonSerializerOptions options, out PooledByteBufferWriter bufferWriter)
public static Utf8JsonWriter RentWriterAndBuffer(JsonSerializerOptions options, out PooledByteBufferWriter bufferWriter) =>
RentWriterAndBuffer(options.GetWriterOptions(), options.DefaultBufferSize, out bufferWriter);

public static Utf8JsonWriter RentWriterAndBuffer(JsonWriterOptions options, int defaultBufferSize, out PooledByteBufferWriter bufferWriter)
{
ThreadLocalState state = t_threadLocalState ??= new();
Utf8JsonWriter writer;
Expand All @@ -24,14 +27,14 @@ public static Utf8JsonWriter RentWriterAndBuffer(JsonSerializerOptions options,
bufferWriter = state.BufferWriter;
writer = state.Writer;

bufferWriter.InitializeEmptyInstance(options.DefaultBufferSize);
writer.Reset(bufferWriter, options.GetWriterOptions());
bufferWriter.InitializeEmptyInstance(defaultBufferSize);
writer.Reset(bufferWriter, options);
}
else
{
// We're in a recursive JsonSerializer call -- return fresh instances.
bufferWriter = new PooledByteBufferWriter(options.DefaultBufferSize);
writer = new Utf8JsonWriter(bufferWriter, options.GetWriterOptions());
bufferWriter = new PooledByteBufferWriter(defaultBufferSize);
writer = new Utf8JsonWriter(bufferWriter, options);
}

return writer;
Expand Down

0 comments on commit 614d864

Please sign in to comment.