Skip to content

Blazor SSR implementation of Fortunes benchmark is considerably slower than Razor Pages implementation #54232

Open
@DamianEdwards

Description

@DamianEdwards

The Blazor SSR implementation of the TechEmpower Fortunes benchmark is quite a bit slower than the Razor Pages implementation.

image

When I initially investigated performance of Blazor SSR vs. Razor Pages for the Fortunes benchmark, the difference was much smaller (single-digit percentage). @sebastienros tracked down the drop to this commit during 8.0.0-preview.7, which suggests that the underlying cause might be the anti-forgery middleware (#50065).

The crank output comparing the Blazor SSR implementation vs. returning RazorComponentResult directly from MapGet vs. Razor Pages seems to indicate that even with anti-forgery middleware removed from the picture (when returning RazorComponentResult directly) the performance is still ~25% lower than Razor Pages (but about 2.4x faster than using MapRazorComponents).

crank output
| db                   | fortunes-blazor | fortunes-blazor-direct |         | fortunes-razorpages |          |
| -------------------- | --------------- | ---------------------- | ------- | ------------------- | -------- |
| Max CPU Usage (%)    |              11 |                     20 | +81.82% |                  22 | +100.00% |
| Max Cores usage (%)  |             308 |                    552 | +79.22% |                 628 | +103.90% |
| Max Working Set (MB) |              51 |                     51 |   0.00% |                  53 |   +3.92% |
| Build Time (ms)      |           1,169 |                  1,484 | +26.95% |               1,221 |   +4.45% |
| Start Time (ms)      |           1,102 |                  1,090 |  -1.09% |               1,150 |   +4.36% |
| Published Size (KB)  |         369,863 |                369,863 |   0.00% |             369,863 |    0.00% |


| application                             | fortunes-blazor | fortunes-blazor-direct |          | fortunes-razorpages |          |
| --------------------------------------- | --------------- | ---------------------- | -------- | ------------------- | -------- |
| Max CPU Usage (%)                       |              99 |                     99 |    0.00% |                  98 |   -1.01% |
| Max Cores usage (%)                     |           2,766 |                  2,760 |   -0.22% |               2,744 |   -0.80% |
| Max Working Set (MB)                    |           1,440 |                  1,320 |   -8.33% |                 555 |  -61.46% |
| Max Private Memory (MB)                 |           2,053 |                  2,058 |   +0.24% |               1,299 |  -36.73% |
| Build Time (ms)                         |           3,792 |                  3,295 |  -13.11% |               3,988 |   +5.17% |
| Start Time (ms)                         |             264 |                    246 |   -6.82% |                 288 |   +9.09% |
| Published Size (KB)                     |         103,944 |                103,944 |    0.00% |             103,950 |   +0.01% |
| Symbols Size (KB)                       |              29 |                     29 |    0.00% |                  28 |   -3.45% |
| .NET Core SDK Version                   |         8.0.100 |                8.0.100 |          |             8.0.100 |          |
| Max CPU Usage (%)                       |              99 |                     99 |   -0.04% |                  98 |   -0.35% |
| Max Working Set (MB)                    |           1,493 |                  1,390 |   -6.91% |                 582 |  -61.04% |
| Max GC Heap Size (MB)                   |             777 |                  1,081 |  +39.21% |                 347 |  -55.34% |
| Size of committed memory by the GC (MB) |           1,110 |                    666 |  -40.00% |                 461 |  -58.52% |
| Max Number of Gen 0 GCs / sec           |            9.00 |                  18.00 | +100.00% |               10.00 |  +11.11% |
| Max Number of Gen 1 GCs / sec           |            2.00 |                   2.00 |    0.00% |                5.00 | +150.00% |
| Max Number of Gen 2 GCs / sec           |            1.00 |                   1.00 |    0.00% |                1.00 |    0.00% |
| Max Gen 0 GC Budget (MB)                |           1,393 |                  1,349 |   -3.16% |                 353 |  -74.66% |
| Max Time in GC (%)                      |            3.00 |                   3.00 |    0.00% |                2.00 |  -33.33% |
| Max Gen 0 Size (B)                      |      93,333,264 |              6,348,152 |  -93.20% |           6,275,496 |  -93.28% |
| Max Gen 1 Size (B)                      |      43,891,864 |             41,113,960 |   -6.33% |          41,080,384 |   -6.41% |
| Max Gen 2 Size (B)                      |      40,472,144 |             38,131,472 |   -5.78% |          12,100,520 |  -70.10% |
| Max LOH Size (B)                        |         187,376 |                187,376 |    0.00% |             188,008 |   +0.34% |
| Max POH Size (B)                        |       1,185,400 |              1,206,000 |   +1.74% |           1,214,240 |   +2.43% |
| Max Allocation Rate (B/sec)             |   3,079,377,968 |          5,908,769,424 |  +91.88% |       3,196,734,984 |   +3.81% |
| Max GC Heap Fragmentation (%)           |          5,015% |                   882% |  -82.41% |              3,130% |  -37.57% |
| # of Assemblies Loaded                  |             118 |                    118 |    0.00% |                 133 |  +12.71% |
| Max Exceptions (#/s)                    |             472 |                    464 |   -1.69% |                 468 |   -0.85% |
| Max Lock Contention (#/s)               |             270 |                    429 |  +58.89% |                 386 |  +42.96% |
| Max ThreadPool Threads Count            |              48 |                     48 |    0.00% |                  48 |    0.00% |
| Max ThreadPool Queue Length             |             205 |                    196 |   -4.39% |                 129 |  -37.07% |
| Max ThreadPool Items (#/s)              |         254,972 |                603,950 | +136.87% |             365,324 |  +43.28% |
| Max Active Timers                       |              12 |                     19 |  +58.33% |                   8 |  -33.33% |
| IL Jitted (B)                           |         859,557 |                773,843 |   -9.97% |             737,378 |  -14.21% |
| Methods Jitted                          |           9,893 |                  8,930 |   -9.73% |               8,445 |  -14.64% |
| Load Working Set - P90 (MB)             |             718 |                    677 |   -5.71% |                 554 |  -22.84% |
| Load CPU Usage - P90 (%)                |              98 |                     97 |   -1.02% |                  96 |   -2.04% |


| load                    | fortunes-blazor | fortunes-blazor-direct |          | fortunes-razorpages |          |
| ----------------------- | --------------- | ---------------------- | -------- | ------------------- | -------- |
| Max CPU Usage (%)       |              13 |                     26 | +100.00% |                  25 |  +92.31% |
| Max Cores usage (%)     |             354 |                    733 | +107.06% |                 705 |  +99.15% |
| Max Working Set (MB)    |              48 |                     46 |   -4.17% |                  46 |   -4.17% |
| Max Private Memory (MB) |             358 |                    358 |    0.00% |                 358 |    0.00% |
| Build Time (ms)         |           3,162 |                  3,311 |   +4.71% |               3,096 |   -2.09% |
| Start Time (ms)         |               0 |                      0 |          |                   0 |          |
| Published Size (KB)     |          72,511 |                 72,511 |    0.00% |              72,511 |    0.00% |
| Symbols Size (KB)       |               0 |                      0 |          |                   0 |          |
| .NET Core SDK Version   |         8.0.100 |                8.0.100 |          |             8.0.100 |          |
| First Request (ms)      |             401 |                    381 |   -4.99% |                 353 |  -11.97% |
| Requests/sec            |          63,172 |                154,367 | +144.36% |             202,153 | +220.00% |
| Requests                |         951,310 |              2,330,895 | +145.02% |           3,052,536 | +220.88% |
| Mean latency (ms)       |            4.61 |                   1.77 |  -61.61% |                1.39 |  -69.85% |
| Max latency (ms)        |           76.03 |                  31.77 |  -58.21% |               36.80 |  -51.60% |
| Bad responses           |               0 |                      0 |          |                   0 |          |
| Socket errors           |               0 |                      0 |          |                   0 |          |
| Read throughput (MB/s)  |          109.47 |                 220.09 | +101.05% |              305.38 | +178.96% |
| Latency 50th (ms)       |            3.55 |                   1.52 |  -57.18% |                1.13 |  -68.17% |
| Latency 75th (ms)       |            5.64 |                   2.08 |  -63.12% |                1.66 |  -70.57% |
| Latency 90th (ms)       |            8.60 |                   2.88 |  -66.51% |                2.23 |  -74.07% |
| Latency 99th (ms)       |           20.73 |                   6.43 |  -68.98% |                6.76 |  -67.39% |

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions