Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing reflection-based json configuration #46303

Conversation

brunolins16
Copy link
Member

@brunolins16 brunolins16 commented Jan 27, 2023

Contributes #46490

Benchmark results

Summary

No negative impact detected.

1 - Request Delegate

Sample

      record Todo(int Id, string Name, bool IsComplete);

      app.MapGet("/requestDelegate", (HttpContext context) 
                   => context.Response.WriteAsJsonAsync(new Todo(1, "teste", true)));

Results

application request-delegate-main request-delegate-dev
CPU Usage (%) 97 97 0.00%
Cores usage (%) 1,164 1,160 -0.34%
Working Set (MB) 197 196 -0.51%
Private Memory (MB) 582 468 -19.59%
Build Time (ms) 1,381 1,388 +0.51%
Start Time (ms) 106 107 +0.94%
Published Size (KB) 90,453 90,453 0.00%
Symbols Size (KB) 21 21 0.00%
.NET Core SDK Version 8.0.100-preview.2.23110.5 8.0.100-preview.2.23110.5
Max CPU Usage (%) 97 97 +0.58%
Max Working Set (MB) 207 204 -1.39%
Max GC Heap Size (MB) 94 95 +1.68%
Size of committed memory by the GC (MB) 129 128 -1.35%
Max Number of Gen 0 GCs / sec 3.00 3.00 0.00%
Max Number of Gen 1 GCs / sec 1.00 1.00 0.00%
Max Number of Gen 2 GCs / sec 1.00 1.00 0.00%
Max Time in GC (%) 0.00 0.00
Max Gen 0 Size (B) 584 584 0.00%
Max Gen 1 Size (B) 3,499,040 2,963,456 -15.31%
Max Gen 2 Size (B) 3,526,904 3,433,176 -2.66%
Max LOH Size (B) 478,840 183,872 -61.60%
Max POH Size (B) 1,187,064 1,187,064 0.00%
Total Allocated Bytes 7,564,279,776 7,626,803,200 +0.83%
Max GC Heap Fragmentation 1 0 -41.85%
# of Assemblies Loaded 88 88 0.00%
Max Exceptions (#/s) 398 373 -6.28%
Max Lock Contention (#/s) 26 18 -30.77%
Max ThreadPool Threads Count 24 23 -4.17%
Max ThreadPool Queue Length 146 122 -16.44%
Max ThreadPool Items (#/s) 726,110 720,117 -0.83%
Max Active Timers 1 1 0.00%
IL Jitted (B) 291,847 289,003 -0.97%
Methods Jitted 3,177 3,147 -0.94%
load request-delegate-main request-delegate-dev
CPU Usage (%) 95 95 0.00%
Cores usage (%) 1,145 1,143 -0.17%
Working Set (MB) 121 121 0.00%
Private Memory (MB) 358 358 0.00%
Start Time (ms) 0 0
First Request (ms) 167 165 -1.20%
Requests/sec 596,981 601,449 +0.75%
Requests 9,014,192 9,080,144 +0.73%
Mean latency (ms) 0.53 0.50 -5.97%
Max latency (ms) 39.70 35.94 -9.47%
Bad responses 0 0
Socket errors 0 0
Read throughput (MB/s) 131.51 132.50 +0.75%
Latency 50th (ms) 0.37 0.37 -0.27%
Latency 75th (ms) 0.43 0.43 -0.69%
Latency 90th (ms) 0.53 0.52 -1.88%
Latency 99th (ms) 6.49 4.62 -28.81%
2 - Http Results

Sample

  public class Message
  {
      public string Text { get; set; }
  }

    app.MapGet("/ok", () => Results.Ok(new Message { Text = "Hello, World!" }));

Results

application map-action-ok-main map-action-ok-dev
CPU Usage (%) 96 96 0.00%
Cores usage (%) 1,153 1,149 -0.35%
Working Set (MB) 194 191 -1.55%
Private Memory (MB) 564 561 -0.53%
Build Time (ms) 1,382 1,387 +0.36%
Start Time (ms) 106 106 0.00%
Published Size (KB) 90,453 90,453 0.00%
Symbols Size (KB) 21 21 0.00%
.NET Core SDK Version 8.0.100-preview.2.23110.5 8.0.100-preview.2.23110.5
Max CPU Usage (%) 99 96 -3.13%
Max Working Set (MB) 204 200 -1.85%
Max GC Heap Size (MB) 96 96 -0.08%
Size of committed memory by the GC (MB) 127 122 -3.52%
Max Number of Gen 0 GCs / sec 4.00 4.00 0.00%
Max Number of Gen 1 GCs / sec 1.00 1.00 0.00%
Max Number of Gen 2 GCs / sec 1.00 1.00 0.00%
Max Time in GC (%) 1.00 2.00 +100.00%
Max Gen 0 Size (B) 584 584 0.00%
Max Gen 1 Size (B) 3,307,464 218,160 -93.40%
Max Gen 2 Size (B) 3,443,168 3,436,232 -0.20%
Max LOH Size (B) 85,512 85,512 0.00%
Max POH Size (B) 1,187,064 1,187,064 0.00%
Total Allocated Bytes 8,280,047,064 8,161,958,168 -1.43%
Max GC Heap Fragmentation 1 0 -79.96%
# of Assemblies Loaded 88 88 0.00%
Max Exceptions (#/s) 362 339 -6.35%
Max Lock Contention (#/s) 549 609 +10.93%
Max ThreadPool Threads Count 22 22 0.00%
Max ThreadPool Queue Length 163 137 -15.95%
Max ThreadPool Items (#/s) 653,202 647,596 -0.86%
Max Active Timers 1 1 0.00%
IL Jitted (B) 288,159 287,854 -0.11%
Methods Jitted 3,159 3,159 0.00%
load map-action-ok-main map-action-ok-dev
CPU Usage (%) 92 91 -1.09%
Cores usage (%) 1,098 1,092 -0.55%
Working Set (MB) 121 121 0.00%
Private Memory (MB) 358 358 0.00%
Start Time (ms) 0 0
First Request (ms) 166 169 +1.81%
Requests/sec 558,759 553,928 -0.86%
Requests 8,437,154 8,363,586 -0.87%
Mean latency (ms) 0.48 0.49 +0.82%
Max latency (ms) 36.06 32.36 -10.26%
Bad responses 0 0
Socket errors 0 0
Read throughput (MB/s) 114.04 113.05 -0.87%
Latency 50th (ms) 0.41 0.41 +0.73%
Latency 75th (ms) 0.48 0.48 +0.63%
Latency 90th (ms) 0.57 0.57 +1.06%
Latency 99th (ms) 1.58 1.74 +10.13%
3 - Type return

Sample

    app.MapGet("/json", new { message = "Hello, World!" );

Results

application map-action-main map-action-dev
CPU Usage (%) 97 97 0.00%
Cores usage (%) 1,167 1,169 +0.17%
Working Set (MB) 199 193 -3.02%
Private Memory (MB) 577 572 -0.87%
Build Time (ms) 1,351 1,362 +0.81%
Start Time (ms) 105 105 0.00%
Published Size (KB) 90,452 90,452 0.00%
Symbols Size (KB) 21 21 0.00%
.NET Core SDK Version 8.0.100-preview.2.23110.5 8.0.100-preview.2.23110.5
Max CPU Usage (%) 97 97 -0.11%
Max Working Set (MB) 209 204 -2.31%
Max GC Heap Size (MB) 91 94 +3.02%
Size of committed memory by the GC (MB) 135 128 -5.70%
Max Number of Gen 0 GCs / sec 2.00 2.00 0.00%
Max Number of Gen 1 GCs / sec 1.00 1.00 0.00%
Max Number of Gen 2 GCs / sec 1.00 1.00 0.00%
Max Time in GC (%) 0.00 0.00
Max Gen 0 Size (B) 584 584 0.00%
Max Gen 1 Size (B) 3,437,264 3,429,712 -0.22%
Max Gen 2 Size (B) 3,476,248 3,397,168 -2.27%
Max LOH Size (B) 183,872 183,872 0.00%
Max POH Size (B) 1,187,064 1,187,064 0.00%
Total Allocated Bytes 4,508,356,032 4,486,275,304 -0.49%
Max GC Heap Fragmentation 1 1 -0.40%
# of Assemblies Loaded 87 87 0.00%
Max Exceptions (#/s) 342 277 -19.01%
Max Lock Contention (#/s) 22 25 +13.64%
Max ThreadPool Threads Count 23 23 0.00%
Max ThreadPool Queue Length 165 129 -21.82%
Max ThreadPool Items (#/s) 790,108 800,531 +1.32%
Max Active Timers 1 1 0.00%
IL Jitted (B) 281,794 281,234 -0.20%
Methods Jitted 3,066 3,063 -0.10%
load map-action-main map-action-dev
CPU Usage (%) 98 98 0.00%
Cores usage (%) 1,179 1,182 +0.25%
Working Set (MB) 121 121 0.00%
Private Memory (MB) 358 358 0.00%
Start Time (ms) 0 0
First Request (ms) 164 165 +0.61%
Requests/sec 638,332 639,254 +0.14%
Requests 9,637,054 9,651,778 +0.15%
Mean latency (ms) 0.49 0.49 -0.68%
Max latency (ms) 44.01 44.37 +0.82%
Bad responses 0 0
Socket errors 0 0
Read throughput (MB/s) 132.10 132.29 +0.14%
Latency 50th (ms) 0.34 0.34 -0.29%
Latency 75th (ms) 0.40 0.40 -0.25%
Latency 90th (ms) 0.50 0.51 +0.40%
Latency 99th (ms) 6.14 5.89 -4.07%
4 - MVC Json

Sample

      [HttpGet("/json-helloworld")]
      [Produces("application/json")]
      public object Json()
      {
          return new { message = "Hello, World!" };
      }   

Results

application mvc-main mvc-dev
CPU Usage (%) 95 94 -1.05%
Cores usage (%) 1,136 1,125 -0.97%
Working Set (MB) 170 173 +1.76%
Private Memory (MB) 159 161 +1.26%
Build Time (ms) 6,513 1,689 -74.07%
Start Time (ms) 248 252 +1.61%
Published Size (KB) 93,488 93,488 0.00%
Symbols Size (KB) 23 23 0.00%
.NET Core SDK Version 8.0.100-preview.2.23110.5 8.0.100-preview.2.23110.5
Max CPU Usage (%) 101 99 -2.61%
Max Working Set (MB) 178 181 +1.49%
Max GC Heap Size (MB) 88 73 -16.68%
Size of committed memory by the GC (MB) 117 119 +2.11%
Max Number of Gen 0 GCs / sec 11.00 11.00 0.00%
Max Number of Gen 1 GCs / sec 2.00 2.00 0.00%
Max Number of Gen 2 GCs / sec 1.00 1.00 0.00%
Max Time in GC (%) 0.00 0.00
Max Gen 0 Size (B) 273,240 273,240 0.00%
Max Gen 1 Size (B) 5,841,600 5,688,888 -2.61%
Max Gen 2 Size (B) 4,300,976 6,114,424 +42.16%
Max LOH Size (B) 209,248 209,248 0.00%
Max POH Size (B) 1,186,016 1,186,016 0.00%
Total Allocated Bytes 25,573,023,096 25,831,533,768 +1.01%
Max GC Heap Fragmentation 17 36 +111.84%
# of Assemblies Loaded 109 109 0.00%
Max Exceptions (#/s) 376 400 +6.38%
Max Lock Contention (#/s) 15 39 +160.00%
Max ThreadPool Threads Count 22 20 -9.09%
Max ThreadPool Queue Length 195 211 +8.21%
Max ThreadPool Items (#/s) 665,406 669,958 +0.68%
Max Active Timers 0 0
IL Jitted (B) 322,232 321,973 -0.08%
Methods Jitted 3,948 3,937 -0.28%
load mvc-main mvc-dev
CPU Usage (%) 51 51 0.00%
Cores usage (%) 609 615 +0.99%
Working Set (MB) 131 121 -7.63%
Private Memory (MB) 358 358 0.00%
Build Time (ms) 6,065 0
Start Time (ms) 0 0
Published Size (KB) 73,153 0
Symbols Size (KB) 0 0
.NET Core SDK Version 7.0.102 0
First Request (ms) 171 173 +1.17%
Requests/sec 248,027 249,735 +0.69%
Requests 3,745,166 3,770,970 +0.69%
Mean latency (ms) 1.25 1.22 -2.40%
Max latency (ms) 179.76 167.73 -6.69%
Bad responses 0 0
Socket errors 0 0
Read throughput (MB/s) 51.33 51.68 +0.68%
Latency 50th (ms) 1.00 0.99 -1.00%
Latency 75th (ms) 1.03 1.03 0.00%
Latency 90th (ms) 1.09 1.08 -0.92%
Latency 99th (ms) 4.67 1.65 -64.67%

@brunolins16
Copy link
Member Author

/benchmark

@brunolins16 brunolins16 added area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels and removed area-runtime labels Feb 1, 2023
@brunolins16 brunolins16 changed the title Changing reflection-base json configuration to PostConfigure Changing reflection-base json configuration Feb 1, 2023
@brunolins16 brunolins16 changed the title Changing reflection-base json configuration Changing reflection-based json configuration Feb 1, 2023
Copy link
Member

@halter73 halter73 left a comment

Choose a reason for hiding this comment

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

Can we undraft this? Has @eiriktsarpalis seen this?

src/Http/Http.Extensions/src/HttpRequestJsonExtensions.cs Outdated Show resolved Hide resolved

if (markAsReadOnly)
{
options.MakeReadOnly();
Copy link
Member

Choose a reason for hiding this comment

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

Would it be simpler to just always mark as read-only? Every time it's false (everywhere but RDF), we're about to write anyway, correct?

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 prefer not set it everywhere and let the serializer call it when needed. If you want I can remove it from here and call MakeReadOnly in RDF only.

src/Shared/Json/JsonSerializerOptionsExtensions.cs Outdated Show resolved Hide resolved
@eerhardt
Copy link
Member

Can you ensure that this doesn't regress size in the Native AOT benchmarks?

@brunolins16
Copy link
Member Author

Can you ensure that this doesn't regress size in the Native AOT benchmarks?

@eerhardt I ran the Native AOT benchmarks (copied the command from the dashboard) and compared with a run using --application.options.outputfiles compiled locally.

application aot-dev aot-main
CPU Usage (%) 88 88 0.00%
Cores usage (%) 2,465 2,464 -0.04%
Working Set (MB) 49 48 -2.04%
Private Memory (MB) 478 478 0.00%
Build Time (ms) 24,935 32,081 +28.66%
Start Time (ms) 52 46 -11.54%
Published Size (KB) 62,328 62,328 0.00%
Symbols Size (KB) 47,519 47,519 0.00%
.NET Core SDK Version 8.0.100-preview.2.23123.10 8.0.100-preview.2.23123.10
load aot-dev aot-main
CPU Usage (%) 19 18 -5.26%
Cores usage (%) 935 878 -6.10%
Working Set (MB) 48 48 0.00%
Private Memory (MB) 358 358 0.00%
Start Time (ms) 0 0
First Request (ms) 47 48 +2.13%
Requests/sec 599,384 597,701 -0.28%
Requests 9,050,637 9,025,325 -0.28%
Mean latency (ms) 0.62 0.66 +6.64%
Max latency (ms) 33.39 35.24 +5.54%
Bad responses 0 0
Socket errors 0 0
Read throughput (MB/s) 327.54 326.62 -0.28%
Latency 50th (ms) 0.36 0.36 -0.55%
Latency 75th (ms) 0.45 0.45 +0.22%
Latency 90th (ms) 1.13 1.37 +21.24%
Latency 99th (ms) 4.27 4.50 +5.39%

Is this comparison enough? What else you usually do for comparison?

@@ -51,36 +44,17 @@ public static class HttpRequestJsonExtensions
/// <param name="options">The serializer options to use when deserializing the content.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
[RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)]
Copy link
Member

@eiriktsarpalis eiriktsarpalis Feb 27, 2023

Choose a reason for hiding this comment

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

I recall @eerhardt mentioning that public ASP.NET APIs should preserve RUC/RDC annotations even if any reflection code is hidden behind a feature flag. Presumably library authors would still need to be warned if calling into these APIs.

@brunolins16
Copy link
Member Author

This dotnet/runtime#83844 will fix everything 😂

@ghost
Copy link

ghost commented Mar 23, 2023

Hi @brunolins16. It looks like you just commented on a closed PR. The team will most probably miss it. If you'd like to bring something important up to their attention, consider filing a new issue and add enough details to build context.

@github-actions github-actions bot locked and limited conversation to collaborators Dec 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-web-frameworks *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels
Projects
None yet
6 participants