Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Port perf changes and issues #41771

Merged
merged 9 commits into from
Oct 16, 2019

Conversation

steveharter
Copy link
Member

The "No Merge" label is there to ensure when this is merged,the individual commits are NOT squashed (one commit here per original commit in master).

Peformance and three bug fixes:
Fixes #40449
Fixes #40704
Fixes #41425

On performance:
• Serialization is ~1.2x to ~1.5x faster than 3.0
• Deserialization is ~1.2x faster than 3.0

Ports the following:

Issue Type 5.0 PR 5.0 Commit Description Customer Impact Risk
40449 Bug 40501 5dbbdfa Change a NullReferenceException to JsonException when invalid JSON is encountered in certain cases. Reported by the community. Invalid JSON can result in a NullReferenceException which is not expected and likely not in any Try\Catch. Low. The fix has been in master for several weeks. Not likely to be “breaking” since changing from NullReferenceException to another (valid) exception is not considered breaking.
40704 Bug 40787 7829d4a Non-ASCII dictionary key names and object property names are always escaped. Reported by the community. Non-ASCII locales have additional JSON payload size and in general this is not expected. Low. The fix has been in master for several weeks. Appropriate tests added.
  Perf 40889 27ddbe9 Minor deserialization perf improvements for collection by removing unnecessary allocations. (perf) Low. The fix has been in master for several weeks.
  Perf 40998 d3c6628 Major perf deserialzation perf gains primarily due to changes to property name lookup. (perf) Low. The fix has been in master for several weeks. Appropriate tests added.
  Perf 41098 017a038 Major serialization perf improvements based on [AggressiveInlining] and enumerator changes. (perf) Low. The fix has been in master for several weeks.
  Perf 41238 527595f Medium perf gains on deserialize and serialize using a variety of changes. (perf) Low. The fix has been in master for two weeks. Appropriate tests added.
  Perf 41363 4cfc7ec Minor perf gains with the JsonCamelCaseNamingPolicy. This decreases warmup time but can help at runtime when using the naming policy on Dictionaries. (perf) Low. The fix has been in master for two weeks.
  Perf 41414 8655ef9 Minor perf gains on deserialization; includes some clean-up and addresses late comments from previous PR. (perf) Low. Appropriate tests added.
41425 Bug 41653 4580a4d A [JsonConverter] attribute when applied to a collection property to specify a custom converter does not work (does nothing). Reported by the community. Having a broken feature is confusing\not expected when encountered. Note there is a work-around to add the converter at run-time (instead of an attribute). Low. The fix is contained in a single method and new tests added.

@steveharter steveharter added * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) area-System.Text.Json labels Oct 14, 2019
@steveharter steveharter added this to the 3.1 milestone Oct 14, 2019
@steveharter steveharter self-assigned this Oct 14, 2019
@ahsonkhan
Copy link
Member

ahsonkhan commented Oct 14, 2019

Question: How much effort would it be to port #40867 as well? Is none of the changes from that PR relevant anymore (it looks like that's the case)? I understand that the code changed since then, but it might be good to keep that history of changes in sync.

That's the only PR tagged for perf not included here (6 of 7 targeted for 5.0 are):
https://github.com/dotnet/corefx/pulls?q=is%3Apr+label%3Aarea-System.Text.Json+label%3Atenet-performance+is%3Aclosed+milestone%3A5.0

Also, were the commits here applied in the same order as they were checked-in to master?

@@ -159,7 +159,8 @@ public static partial class JsonSerializer
}
}

writer.WritePropertyName(key);
JsonEncodedText escapedKey = JsonEncodedText.Encode(key, options.Encoder);
Copy link
Member

@ahsonkhan ahsonkhan Oct 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an incorrect change. It is undoing the optimizations from #40991 (comment) / #41210

Please verify that nothing else from that PR is being changed, unintentionally. Also, how did this diff fall through?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Updated that and re-verified other commits.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, how did this diff fall through?

It didn't. That fix was done in an earlier change and was out-of-order and manually applied.

@steveharter
Copy link
Member Author

How much effort would it be to port #40867 as well?

The code that was changed with #40867 was replaced with #41098 (included here)

@steveharter
Copy link
Member Author

Also, were the commits here applied in the same order as they were checked-in to master?

Yes

@danmoseley danmoseley added the * NO SQUASH * The PR should not be squashed label Oct 15, 2019
@ericstj ericstj added the Servicing-consider Issue for next servicing release review label Oct 15, 2019
@steveharter
Copy link
Member Author

I did a manual diff between 5.0 and this PR and found this perf PR (#40114) that I just adorned with "performance" label.

It has minor perf benefits, but is the only current 5.0 perf issue AFAIK not ported here. We should consider adding here (or in a subsequent PR).

@ericstj
Copy link
Member

ericstj commented Oct 15, 2019

We can do in subsequent PR. I've reviewed all the commits and am OK with bringing them over to 3.1. We just need to document #40787.

@danmoseley
Copy link
Member

As far as I/tactics are concerned, this can be merged.

BTW if someone accidentally squashes, I suggest reversing that commit and then doing it again so we have that nice history. I only mention this because I can totally imagine myself doing this 😄

// "encoder: null" is used since the literal values of "Key" and "Value" should not normally be escaped
// unless a custom encoder is used that escapes these ASCII characters (rare).
// Also by not specifying an encoder allows the values to be cached statically here.
private static readonly JsonEncodedText _keyName = JsonEncodedText.Encode(KeyName, encoder: null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of scope of this PR, but we should pass in the user-defined encoder for this (and not null). Though unlikely, if a user creates an encoder that escapes everything, then the payload would be incorrect.

@steveharter steveharter merged commit 28875ae into dotnet:release/3.1 Oct 16, 2019
@steveharter steveharter deleted the PortJsonIssuesTo31 branch October 16, 2019 22:28
@steveharter steveharter removed the * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) label Oct 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Text.Json * NO SQUASH * The PR should not be squashed Servicing-consider Issue for next servicing release review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants