diff --git a/benchmarkapps/Benchmarks/Benchmarks.csproj b/benchmarkapps/Benchmarks/Benchmarks.csproj
index 3a791502b2..b85c439bc7 100644
--- a/benchmarkapps/Benchmarks/Benchmarks.csproj
+++ b/benchmarkapps/Benchmarks/Benchmarks.csproj
@@ -5,13 +5,15 @@
$(BenchmarksTargetFramework)
-
+
+
+
-
+
diff --git a/benchmarkapps/Benchmarks/Program.cs b/benchmarkapps/Benchmarks/Program.cs
index 5545205d13..a37a131d9c 100644
--- a/benchmarkapps/Benchmarks/Program.cs
+++ b/benchmarkapps/Benchmarks/Program.cs
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
@@ -16,15 +17,37 @@ namespace Benchmarks
public static IWebHostBuilder GetWebHostBuilder(string[] args)
{
var config = new ConfigurationBuilder()
+ .AddCommandLine(args)
+ .AddEnvironmentVariables(prefix: "RoutingBenchmarks_")
.Build();
// Consoler logger has a major impact on perf results, so do not use
// default builder.
- return new WebHostBuilder()
- .UseConfiguration(config)
- .UseKestrel()
- .UseStartup();
+ var webHostBuilder = new WebHostBuilder()
+ .UseConfiguration(config)
+ .UseKestrel();
+
+ var scenario = config["scenarios"]?.ToLower();
+ if (scenario == "plaintextdispatcher")
+ {
+ webHostBuilder.UseStartup();
+ // for testing
+ webHostBuilder.UseSetting("Startup", nameof(StartupUsingDispatcher));
+ }
+ else if (scenario == "plaintextrouting")
+ {
+ webHostBuilder.UseStartup();
+ // for testing
+ webHostBuilder.UseSetting("Startup", nameof(StartupUsingRouting));
+ }
+ else
+ {
+ throw new InvalidOperationException(
+ $"Invalid scenario '{scenario}'. Allowed scenarios are PlaintextDispatcher and PlaintextRouting");
+ }
+
+ return webHostBuilder;
}
}
}
diff --git a/benchmarkapps/Benchmarks/StartupUsingDispatcher.cs b/benchmarkapps/Benchmarks/StartupUsingDispatcher.cs
new file mode 100644
index 0000000000..bfd6069eca
--- /dev/null
+++ b/benchmarkapps/Benchmarks/StartupUsingDispatcher.cs
@@ -0,0 +1,50 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Text;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Routing;
+using Microsoft.AspNetCore.Routing.Matchers;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Benchmarks
+{
+ public class StartupUsingDispatcher
+ {
+ private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddRouting();
+
+ services.AddDispatcher(options =>
+ {
+ options.DataSources.Add(new DefaultEndpointDataSource(new[]
+ {
+ new MatcherEndpoint(
+ invoker: (next) => (httpContext) =>
+ {
+ var response = httpContext.Response;
+ var payloadLength = _helloWorldPayload.Length;
+ response.StatusCode = 200;
+ response.ContentType = "text/plain";
+ response.ContentLength = payloadLength;
+ return response.Body.WriteAsync(_helloWorldPayload, 0, payloadLength);
+ },
+ template: "/plaintext",
+ values: new { },
+ order: 0,
+ metadata: EndpointMetadataCollection.Empty,
+ displayName: "Plaintext"),
+ }));
+ });
+ }
+
+ public void Configure(IApplicationBuilder app)
+ {
+ app.UseDispatcher();
+
+ app.UseEndpoint();
+ }
+ }
+}
\ No newline at end of file
diff --git a/benchmarkapps/Benchmarks/Startup.cs b/benchmarkapps/Benchmarks/StartupUsingRouting.cs
similarity index 96%
rename from benchmarkapps/Benchmarks/Startup.cs
rename to benchmarkapps/Benchmarks/StartupUsingRouting.cs
index e8c51cbaeb..d9e2999af3 100644
--- a/benchmarkapps/Benchmarks/Startup.cs
+++ b/benchmarkapps/Benchmarks/StartupUsingRouting.cs
@@ -8,7 +8,7 @@ using System.Text;
namespace Benchmarks
{
- public class Startup
+ public class StartupUsingRouting
{
private static readonly byte[] _helloWorldPayload = Encoding.UTF8.GetBytes("Hello, World!");
diff --git a/benchmarkapps/Benchmarks/benchmarks.json b/benchmarkapps/Benchmarks/benchmarks.json
index edb513e2dd..59cfd09eb7 100644
--- a/benchmarkapps/Benchmarks/benchmarks.json
+++ b/benchmarkapps/Benchmarks/benchmarks.json
@@ -15,5 +15,8 @@
},
"PlaintextRouting": {
"Path": "/plaintext"
+ },
+ "PlaintextDispatcher": {
+ "Path": "/plaintext"
}
-}
+}
\ No newline at end of file
diff --git a/build/dependencies.props b/build/dependencies.props
index bb2e38a84e..c615caa103 100644
--- a/build/dependencies.props
+++ b/build/dependencies.props
@@ -17,6 +17,8 @@
2.2.0-preview1-34326
2.2.0-preview1-34326
2.2.0-preview1-34326
+ 2.2.0-preview1-34326
+ 2.2.0-preview1-34326
2.2.0-preview1-34326
2.2.0-preview1-34326
2.2.0-preview1-34326
diff --git a/test/Microsoft.AspNetCore.Routing.FunctionalTests/Benchmarks/DispatcherTest.cs b/test/Microsoft.AspNetCore.Routing.FunctionalTests/Benchmarks/DispatcherTest.cs
new file mode 100644
index 0000000000..3b963b56a5
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Routing.FunctionalTests/Benchmarks/DispatcherTest.cs
@@ -0,0 +1,60 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+#if NETCOREAPP2_2
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.TestHost;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Routing.FunctionalTests
+{
+ public class DispatcherTest : IDisposable
+ {
+ private readonly HttpClient _client;
+ private readonly TestServer _testServer;
+
+ public DispatcherTest()
+ {
+ // This switch and value are set by benchmark server when running the app for profiling.
+ var args = new[] { "--scenarios", "PlaintextDispatcher" };
+ var webHostBuilder = Benchmarks.Program.GetWebHostBuilder(args);
+
+ // Make sure we are using the right startup
+ var startupName = webHostBuilder.GetSetting("Startup");
+ Assert.Equal(nameof(Benchmarks.StartupUsingDispatcher), startupName);
+
+ _testServer = new TestServer(webHostBuilder);
+ _client = _testServer.CreateClient();
+ _client.BaseAddress = new Uri("http://localhost");
+ }
+
+ [Fact]
+ public async Task RouteEndpoint_ReturnsPlaintextResponse()
+ {
+ // Arrange
+ var expectedContentType = "text/plain";
+ var expectedContent = "Hello, World!";
+
+ // Act
+ var response = await _client.GetAsync("/plaintext");
+
+ // Assert
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.NotNull(response.Content);
+ Assert.NotNull(response.Content.Headers.ContentType);
+ Assert.Equal(expectedContentType, response.Content.Headers.ContentType.MediaType);
+ var actualContent = await response.Content.ReadAsStringAsync();
+ Assert.Equal(expectedContent, actualContent);
+ }
+
+ public void Dispose()
+ {
+ _testServer.Dispose();
+ _client.Dispose();
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.Routing.FunctionalTests/BenchmarksTest.cs b/test/Microsoft.AspNetCore.Routing.FunctionalTests/Benchmarks/RoutingTest.cs
similarity index 77%
rename from test/Microsoft.AspNetCore.Routing.FunctionalTests/BenchmarksTest.cs
rename to test/Microsoft.AspNetCore.Routing.FunctionalTests/Benchmarks/RoutingTest.cs
index 30b8411b9c..ae4ef90f06 100644
--- a/test/Microsoft.AspNetCore.Routing.FunctionalTests/BenchmarksTest.cs
+++ b/test/Microsoft.AspNetCore.Routing.FunctionalTests/Benchmarks/RoutingTest.cs
@@ -11,14 +11,21 @@ using Xunit;
namespace Microsoft.AspNetCore.Routing.FunctionalTests
{
- public class BenchmarksTest : IDisposable
+ public class RoutingTest : IDisposable
{
private readonly HttpClient _client;
private readonly TestServer _testServer;
- public BenchmarksTest()
+ public RoutingTest()
{
- var webHostBuilder = Benchmarks.Program.GetWebHostBuilder(args: null);
+ // This switch and value are set by benchmark server when running the app for profiling.
+ var args = new[] { "--scenarios", "PlaintextRouting" };
+ var webHostBuilder = Benchmarks.Program.GetWebHostBuilder(args);
+
+ // Make sure we are using the right startup
+ var startupName = webHostBuilder.GetSetting("Startup");
+ Assert.Equal(nameof(Benchmarks.StartupUsingRouting), startupName);
+
_testServer = new TestServer(webHostBuilder);
_client = _testServer.CreateClient();
_client.BaseAddress = new Uri("http://localhost");