Skip to content

Conversation

@jozkee
Copy link
Member

@jozkee jozkee commented Apr 16, 2020

Fixes #34440

There was a considerable performance regression compared against Microsoft.AspNetCore.Blazor.HttpClient caused by always instantiating a JsonSerializerOptions object when not provided, which means that System.Net.Http.Json was not actively using the caching mechanism of the JsonSerializer for types and converters.

I got the following results using the aspnet/Benchmarks repo to measure the amount of requests made to a simple WeatherForecast app that returns a List<WeatherForecast>.

The scenario keeps a thread sending Get requests for the specified duration (15s) after a specified warm-up time lapse (15s).

The benchmarks used can be found in https://github.com/Jozkee/HttpJsonBenchmarks.

I ran the scenarios 5 times each in order to get a larger sample.

I also ensured that the same version of System.Text.Json was being used (4.7.1 latest stable).

Results

Microsoft.AspNetCore.Blazor.HttpClient Version 3.2.0-preview3.20168.3
[client] 55458 iterations in 15s
[client] 53794 iterations in 15s
[client] 52779 iterations in 15s
[client] 53429 iterations in 15s
[client] 51582 iterations in 15s

System.Net.Http.Json Version 3.2.0-preview3.20175.8 Before fix
[client] 13159 iterations in 15s
[client] 12441 iterations in 15s

System.Net.Http.Json 3.2.0-dev (Private build) After fix
[client] 55352 iterations in 15s
[client] 51981 iterations in 15s
[client] 53777 iterations in 15s
[client] 52569 iterations in 15s
[client] 52655 iterations in 15s

Note: There are further optimizations that can be made/be explored, specially on the Post/Put methods but those transcend the quick gain of using the static options for cache on serialization.

cc @ericstj @joperezr @layomia

@ghost
Copy link

ghost commented Apr 16, 2020

Tagging subscribers to this area: @dotnet/ncl
Notify danmosemsft if you want to be subscribed.

@davidsh davidsh added this to the 5.0 milestone Apr 16, 2020
internal const string JsonMediaType = "application/json";
internal const string JsonType = "application";
internal const string JsonSubtype = "json";
private static MediaTypeHeaderValue DefaultMediaType
Copy link
Contributor

Choose a reason for hiding this comment

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

@jozkee Could we squeeze a bit more performance out of it by also switching to a field and reusing the default media type instance instead of having the lambda?

        private static readonly MediaTypeHeaderValue s_defaultMediaType
            = new MediaTypeHeaderValue(JsonMediaType) { CharSet = "utf-8" };

Copy link
Member Author

Choose a reason for hiding this comment

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

I did consider that as well, but as per @scalablecory's, we must not re-use this, it could be modified or disposed on a request, or it can be intercepted by a DelegatingHandler.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GetFromJsonAsync is ~20% slower than GetJsonAsync in Blazor WASM

7 participants