Skip to content

Update Fortunes to use Razor templating#1801

Merged
DamianEdwards merged 9 commits intomainfrom
damianedwards/razor-fortunes
Mar 13, 2023
Merged

Update Fortunes to use Razor templating#1801
DamianEdwards merged 9 commits intomainfrom
damianedwards/razor-fortunes

Conversation

@DamianEdwards
Copy link
Member

@DamianEdwards DamianEdwards commented Mar 1, 2023

UPDATED: This has been updated on top of @roji's UTF8 changes. Please take a look!

Updates the Fortunes implementations for Minimal and Platform to use Razor .cshtml templates with custom base classes intended for rendering without MVC.

Minimal Results

The new Fortunes Razor implementation for Minimal APIs shows an 88% improvement, possibly due to a large reduction in lock contention and more efficient rendering (e.g. no int.ToString(), optimized HtmlEncoder settings, etc.):

application minimal_fortunes minimal_fortunes_razor
CPU Usage (%) 96 97 +1.04%
Cores usage (%) 2,698 2,718 +0.74%
Working Set (MB) 511 514 +0.59%
Private Memory (MB) 1,267 1,268 +0.08%
Build Time (ms) 2,987 6,586 +120.49%
Start Time (ms) 191 223 +16.75%
Published Size (KB) 91,826 91,885 +0.06%
Symbols Size (KB) 23 52 +126.09%
.NET Core SDK Version 8.0.100-preview.3.23153.4 8.0.100-preview.3.23153.4
Max CPU Usage (%) 96 97 +0.59%
Max Working Set (MB) 536 536 +0.06%
Max GC Heap Size (MB) 347 348 +0.22%
Size of committed memory by the GC (MB) 440 439 -0.33%
Max Number of Gen 0 GCs / sec 4.00 5.00 +25.00%
Max Number of Gen 1 GCs / sec 1.00 2.00 +100.00%
Max Number of Gen 2 GCs / sec 1.00 1.00 0.00%
Max Time in GC (%) 0.00 1.00 +∞%
Max Gen 0 Size (B) 1,456,232 1,598,184 +9.75%
Max Gen 1 Size (B) 20,806,944 19,129,336 -8.06%
Max Gen 2 Size (B) 6,448,144 6,525,640 +1.20%
Max LOH Size (B) 92,112 92,416 +0.33%
Max POH Size (B) 1,190,136 1,231,336 +3.46%
Max Allocation Rate (B/sec) 898,921,040 1,487,158,976 +65.44%
Max GC Heap Fragmentation 63 23 -62.86%
# of Assemblies Loaded 103 109 +5.83%
Max Exceptions (#/s) 487 457 -6.16%
Max Lock Contention (#/s) 11,343 1,071 -90.56%
Max ThreadPool Threads Count 48 48 0.00%
Max ThreadPool Queue Length 54 98 +81.48%
Max ThreadPool Items (#/s) 302,489 528,047 +74.57%
Max Active Timers 13 6 -53.85%
IL Jitted (B) 448,470 458,872 +2.32%
Methods Jitted 4,588 4,787 +4.34%
load minimal_fortunes minimal_fortunes_razor
CPU Usage (%) 27 27 0.00%
Cores usage (%) 762 761 -0.13%
Working Set (MB) 48 48 0.00%
Private Memory (MB) 358 358 0.00%
Start Time (ms) 0 0
First Request (ms) 445 482 +8.31%
Requests/sec 140,567 264,392 +88.09%
Requests 2,122,481 3,992,159 +88.09%
Mean latency (ms) 1.91 1.03 -46.07%
Max latency (ms) 21.87 17.48 -20.07%
Bad responses 0 0
Socket errors 0 0
Read throughput (MB/s) 241.17 357.04 +48.04%
Latency 50th (ms) 1.70 0.87 -48.82%
Latency 75th (ms) 2.40 1.25 -47.92%
Latency 90th (ms) 3.25 1.69 -48.00%
Latency 99th (ms) 6.47 4.02 -37.87%

Platform Results

The new Platform-level Fortunes Razor implementation shows a drop of only 2.4% from the previous non-templated platform implementation from before @roji's UTF8 changes, and still above 460K RPS:

db platform_fortunes platform_fortunes_razor
CPU Usage (%) 34 34 0.00%
Cores usage (%) 962 950 -1.25%
Working Set (MB) 45 46 +2.22%
Build Time (ms) 1,400 1,832 +30.86%
Start Time (ms) 463 449 -3.02%
Published Size (KB) 523,835 523,880 +0.01%
application platform_fortunes platform_fortunes_razor
CPU Usage (%) 96 97 +1.04%
Cores usage (%) 2,694 2,708 +0.52%
Working Set (MB) 566 574 +1.41%
Private Memory (MB) 1,312 1,330 +1.37%
Build Time (ms) 3,437 6,523 +89.79%
Start Time (ms) 1,835 1,838 +0.16%
Published Size (KB) 96,308 96,583 +0.29%
Symbols Size (KB) 44 53 +20.45%
.NET Core SDK Version 8.0.100-preview.3.23153.4 8.0.100-preview.3.23159.20
Max CPU Usage (%) 96 97 +1.21%
Max Working Set (MB) 593 602 +1.43%
Max GC Heap Size (MB) 338 344 +1.79%
Size of committed memory by the GC (MB) 503 509 +1.27%
Max Number of Gen 0 GCs / sec 7.00 6.00 -14.29%
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 (%) 1.00 9.00 +800.00%
Max Gen 0 Size (B) 3,871,184 4,338,176 +12.06%
Max Gen 1 Size (B) 44,041,448 40,763,336 -7.44%
Max Gen 2 Size (B) 10,683,688 18,575,480 +73.87%
Max LOH Size (B) 240,440 241,072 +0.26%
Max POH Size (B) 4,362,536 4,427,840 +1.50%
Max Allocation Rate (B/sec) 2,139,849,232 1,701,910,640 -20.47%
Max GC Heap Fragmentation 20 34 +67.99%
# of Assemblies Loaded 80 87 +8.75%
Max Exceptions (#/s) 966 955 -1.14%
Max Lock Contention (#/s) 5,646 1,920 -65.99%
Max ThreadPool Threads Count 48 48 0.00%
Max ThreadPool Queue Length 207 179 -13.53%
Max ThreadPool Items (#/s) 725,577 694,118 -4.34%
Max Active Timers 12 10 -16.67%
IL Jitted (B) 388,331 393,443 +1.32%
Methods Jitted 4,229 4,391 +3.83%
load platform_fortunes platform_fortunes_razor
CPU Usage (%) 40 39 -2.50%
Cores usage (%) 1,107 1,090 -1.54%
Working Set (MB) 48 48 0.00%
Private Memory (MB) 363 363 0.00%
Start Time (ms) 0 0
First Request (ms) 109 109 0.00%
Requests/sec 474,912 463,480 -2.41%
Requests 7,171,071 6,998,507 -2.41%
Mean latency (ms) 1.16 1.16 0.00%
Max latency (ms) 31.44 21.73 -30.88%
Bad responses 0 0
Socket errors 0 0
Read throughput (MB/s) 616.41 608.20 -1.33%
Latency 50th (ms) 1.01 1.04 +2.97%
Latency 75th (ms) 1.22 1.27 +4.10%
Latency 90th (ms) 1.52 1.58 +3.95%
Latency 99th (ms) 4.24 4.35 +2.59%

Updates the Fortunes implementations for Minimal and Platform to use Razor .cshtml templates with custom base classes intended for rendering using the RazorSlices package (no MVC).
@DamianEdwards DamianEdwards force-pushed the damianedwards/razor-fortunes branch from 306fe89 to aba8713 Compare March 10, 2023 20:42
@DamianEdwards DamianEdwards marked this pull request as ready for review March 10, 2023 20:47
@DamianEdwards DamianEdwards merged commit f5c0016 into main Mar 13, 2023
@DamianEdwards DamianEdwards deleted the damianedwards/razor-fortunes branch March 13, 2023 20:50
}

private void OutputFortunes(PipeWriter pipeWriter, List<Fortune> model)
private ValueTask OutputFortunes<TModel>(PipeWriter pipeWriter, TModel model, SliceFactory<TModel> templateFactory)
Copy link
Contributor

Choose a reason for hiding this comment

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

Might as well just return Task here and then pass through in the other methods if you are just going to await in those ones?

Copy link
Member

Choose a reason for hiding this comment

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

Those methods also need to await the LoadFortunesRows() calls so you can't just return the Task.

Copy link
Contributor

Choose a reason for hiding this comment

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

nvm you have to await anyway

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants