Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
Consider this bare-bones .net 6 app (Github repo linked below):
// Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
// Option 1: "Fast"
// app.MapGet("/home/content", () => "Hello World!");
// Option 2: "Slow"
// app.MapControllerRoute("default", "{controller}/{action}");
app.Run();
// HomeController.cs
using Microsoft.AspNetCore.Mvc;
namespace WebApplication27.Controllers;
public class HomeController : Controller
{
public ContentResult Content()
{
return Content("hello world");
}
}
If I deploy this app to Azure App Service with "Option 1 (fast)" uncommented (i.e. using MapGet
) and use the App Service Metrics blade to measure the average response time for sequential requests to /home/content
(with a 100ms wait between each request) over a time span of many minutes, the average response time is of the order of just a few milliseconds 👍 .
If I then redeploy with nothing changed except for uncommenting "Option 2 (slow)" instead (i.e. using MapControllerRoute
), the average response time becomes of the order of 20 milliseconds
Is this "by design"? That is, is this overhead of using this standard MapControllerRoute
expected? Considering how simple this app is, I was quite surprised to see how much the average response time (for every request) increased when using Option 2, i.e. when invoking the controller-routing middleware.
Is there anything that could be done for this bare-bones app to improve the performance of this MapControllerRoute
option?
Some related notes for context:
-
I have a much more complex .net core app deployed to App Service that interacts with various dependencies (e.g. database) and has an average production response time of between 40-50ms. The same test based on a copy of our production app (not included here) showed the same routing performance hit. That is, this routing performance hit of ~20ms for every requested controller action seems to be responsible for a significant portion of my average production response time. If there were a way to eliminate this ~20ms routing cost (while still using controllers) we could significantly optimize our response time.
-
On my local dev machine (a high-end ThinkPad X1), the average response time was 0.750ms for the
MapGet
case and 1.250ms for theMapControllerRoute
case (i.e. not quite as pronounced). The metrics shown above were from an App Service Plan at level S1, which is a "standard" Azure App Service plan level for production workloads. -
Using
MapDynamicControllerRoute
has similar performance toMapControllerRoute
. -
I tried both 32-bit and 64-bit App Service options (same results).
-
I also tried a .net 5 app with the same configuration (same results).
Expected Behavior
Although we of course understand that controller-based routing is more sophisticated, we would expect a simple app like this (i.e. a single controller) to not have such a performance regression for every request when using MapControllerRoute
instead of MapGet
.
Steps To Reproduce
Minimal repo project:
https://github.com/samcic/WebApplication27
Exceptions (if any)
N/A
.NET Version
6.0.101
Anything else?
Azure App Service Test Environment:
App Service Plan Level: S1
IDE: VS2022 17.0.4
> dotnet --info
.NET SDK (reflecting any global.json):
Version: 6.0.101
Commit: ef49f6213a
Runtime Environment:
OS Name: Windows
OS Version: 10.0.19042
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\6.0.101\
Host (useful for support):
Version: 6.0.1
Commit: 3a25a7f1cc
.NET SDKs installed:
2.1.701 [C:\Program Files\dotnet\sdk]
2.1.801 [C:\Program Files\dotnet\sdk]
2.2.207 [C:\Program Files\dotnet\sdk]
2.2.301 [C:\Program Files\dotnet\sdk]
2.2.401 [C:\Program Files\dotnet\sdk]
3.0.100 [C:\Program Files\dotnet\sdk]
3.1.403 [C:\Program Files\dotnet\sdk]
5.0.300 [C:\Program Files\dotnet\sdk]
6.0.101 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.2.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 5.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 6.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET runtimes or SDKs:
https://aka.ms/dotnet-download