From 5ed24429e72ea7ed7348a5b3698c82d1a13a602f Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Wed, 3 Aug 2022 21:34:50 +0100 Subject: [PATCH] Fix JSON perf regressions reported by #73242. (#73306) --- .../JsonSerializer.Read.Stream.cs | 22 +++++-------------- .../JsonSerializer.Write.Stream.cs | 19 +++++----------- .../Text/Json/Serialization/ReadStack.cs | 3 ++- .../Text/Json/Serialization/WriteStack.cs | 5 ++++- 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs index 833b391752db77..2690a5f4c856a7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs @@ -431,12 +431,8 @@ private static async IAsyncEnumerable CreateAsyncEnumerableDeserializer< Debug.Assert(queueTypeInfo.IsConfigured); JsonSerializerOptions options = queueTypeInfo.Options; var bufferState = new ReadBufferState(options.DefaultBufferSize); - ReadStack readStack = new ReadStack - { - SupportContinuation = true - }; - - readStack.Initialize(queueTypeInfo); + ReadStack readStack = default; + readStack.Initialize(queueTypeInfo, supportContinuation: true); var jsonReaderState = new JsonReaderState(options.GetReaderOptions()); @@ -475,11 +471,8 @@ private static async IAsyncEnumerable CreateAsyncEnumerableDeserializer< Debug.Assert(jsonTypeInfo.IsConfigured); JsonSerializerOptions options = jsonTypeInfo.Options; var bufferState = new ReadBufferState(options.DefaultBufferSize); - ReadStack readStack = new ReadStack - { - SupportContinuation = true - }; - readStack.Initialize(jsonTypeInfo); + ReadStack readStack = default; + readStack.Initialize(jsonTypeInfo, supportContinuation: true); var jsonReaderState = new JsonReaderState(options.GetReaderOptions()); try @@ -508,11 +501,8 @@ private static async IAsyncEnumerable CreateAsyncEnumerableDeserializer< Debug.Assert(jsonTypeInfo.IsConfigured); JsonSerializerOptions options = jsonTypeInfo.Options; var bufferState = new ReadBufferState(options.DefaultBufferSize); - ReadStack readStack = new ReadStack - { - SupportContinuation = true - }; - readStack.Initialize(jsonTypeInfo); + ReadStack readStack = default; + readStack.Initialize(jsonTypeInfo, supportContinuation: true); var jsonReaderState = new JsonReaderState(options.GetReaderOptions()); try diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs index d6c4734bfc5d02..a58ad2d7e40d47 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs @@ -314,15 +314,10 @@ private static async Task WriteStreamAsync( using (var bufferWriter = new PooledByteBufferWriter(options.DefaultBufferSize)) using (var writer = new Utf8JsonWriter(bufferWriter, writerOptions)) { - WriteStack state = new WriteStack - { - CancellationToken = cancellationToken, - SupportContinuation = true, - SupportAsync = true, - }; - + WriteStack state = default; jsonTypeInfo = ResolvePolymorphicTypeInfo(value, jsonTypeInfo, out state.IsPolymorphicRootValue); - state.Initialize(jsonTypeInfo); + state.Initialize(jsonTypeInfo, supportAsync: true, supportContinuation: true); + state.CancellationToken = cancellationToken; bool isFinalBlock; @@ -395,13 +390,9 @@ private static void WriteStream( using (var bufferWriter = new PooledByteBufferWriter(options.DefaultBufferSize)) using (var writer = new Utf8JsonWriter(bufferWriter, writerOptions)) { - WriteStack state = new WriteStack - { - SupportContinuation = true - }; - + WriteStack state = default; jsonTypeInfo = ResolvePolymorphicTypeInfo(value, jsonTypeInfo, out state.IsPolymorphicRootValue); - state.Initialize(jsonTypeInfo); + state.Initialize(jsonTypeInfo, supportContinuation: true, supportAsync: false); bool isFinalBlock; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs index ee348f63aae552..0cfeb6e1a09ab6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs @@ -93,7 +93,7 @@ private void EnsurePushCapacity() } } - internal void Initialize(JsonTypeInfo jsonTypeInfo) + internal void Initialize(JsonTypeInfo jsonTypeInfo, bool supportContinuation = false) { JsonSerializerOptions options = jsonTypeInfo.Options; if (options.ReferenceHandlingStrategy == ReferenceHandlingStrategy.Preserve) @@ -106,6 +106,7 @@ internal void Initialize(JsonTypeInfo jsonTypeInfo) Current.JsonPropertyInfo = jsonTypeInfo.PropertyInfoForTypeInfo; Current.NumberHandling = Current.JsonPropertyInfo.EffectiveNumberHandling; Current.CanContainMetadata = PreserveReferences || jsonTypeInfo.PolymorphicTypeResolver?.UsesTypeDiscriminators == true; + SupportContinuation = supportContinuation; } public void Push() diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs index 18a36d8680d7b1..6910d2e19fd31d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs @@ -139,14 +139,17 @@ private void EnsurePushCapacity() } } - internal void Initialize(JsonTypeInfo jsonTypeInfo) + internal void Initialize(JsonTypeInfo jsonTypeInfo, bool supportContinuation = false, bool supportAsync = false) { + Debug.Assert(!supportAsync || supportContinuation, "supportAsync must imply supportContinuation"); Debug.Assert(!IsContinuation); Debug.Assert(CurrentDepth == 0); Current.JsonTypeInfo = jsonTypeInfo; Current.JsonPropertyInfo = jsonTypeInfo.PropertyInfoForTypeInfo; Current.NumberHandling = Current.JsonPropertyInfo.EffectiveNumberHandling; + SupportContinuation = supportContinuation; + SupportAsync = supportAsync; JsonSerializerOptions options = jsonTypeInfo.Options; if (options.ReferenceHandlingStrategy != ReferenceHandlingStrategy.None)