From b1a45eb8099b33d95cb0edcefab8cb8ec50f02c8 Mon Sep 17 00:00:00 2001
From: James Newton-King <james@newtonking.com>
Date: Tue, 3 Mar 2020 17:17:06 +1300
Subject: [PATCH] Update BenchmarkDotNet and add Http2Connection benchmark
 (#19482)

---
 eng/Versions.props                            |   2 +-
 .../IIS.Performance/FirstRequestConfig.cs     |   4 +-
 .../Http2ConnectionBenchmark.cs               | 101 ++++++++++++++++++
 ...pNetCore.Server.Kestrel.Performance.csproj |   4 +-
 .../Mocks/MockDuplexPipe.cs                   |  19 ++++
 .../Mocks/MockSystemClock.cs                  |  15 +++
 .../Mocks/MockTimeoutControl.cs               |  62 +++++++++++
 .../Mocks/NullPipeWriter.cs                   |   3 +-
 .../test/PipeWriterHttp2FrameExtensions.cs    |  78 ++++++++++++++
 .../Http2/Http2TestBase.cs                    |  80 +++-----------
 .../BenchmarkRunner/DefaultCoreConfig.cs      |   2 +-
 .../DefaultCorePerfLabConfig.cs               |  13 +--
 .../DefaultCoreValidationConfig.cs            |   4 +-
 .../ParamsDisplayInfoColumn.cs                |   8 +-
 14 files changed, 308 insertions(+), 87 deletions(-)
 create mode 100644 src/Servers/Kestrel/perf/Kestrel.Performance/Http2ConnectionBenchmark.cs
 create mode 100644 src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockDuplexPipe.cs
 create mode 100644 src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockSystemClock.cs
 create mode 100644 src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTimeoutControl.cs
 create mode 100644 src/Servers/Kestrel/shared/test/PipeWriterHttp2FrameExtensions.cs

diff --git a/eng/Versions.props b/eng/Versions.props
index f11bb927065..567b25138bd 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -220,7 +220,7 @@
     <MicrosoftAspNetCoreAzureAppServicesSiteExtension31PackageVersion>3.1.3</MicrosoftAspNetCoreAzureAppServicesSiteExtension31PackageVersion>
     <!-- 3rd party dependencies -->
     <AngleSharpPackageVersion>0.9.9</AngleSharpPackageVersion>
-    <BenchmarkDotNetPackageVersion>0.10.13</BenchmarkDotNetPackageVersion>
+    <BenchmarkDotNetPackageVersion>0.12.0</BenchmarkDotNetPackageVersion>
     <CastleCorePackageVersion>4.2.1</CastleCorePackageVersion>
     <FSharpCorePackageVersion>4.2.1</FSharpCorePackageVersion>
     <GoogleProtobufPackageVersion>3.8.0</GoogleProtobufPackageVersion>
diff --git a/src/Servers/IIS/IIS/benchmarks/IIS.Performance/FirstRequestConfig.cs b/src/Servers/IIS/IIS/benchmarks/IIS.Performance/FirstRequestConfig.cs
index 727746871fc..c048b28f8dc 100644
--- a/src/Servers/IIS/IIS/benchmarks/IIS.Performance/FirstRequestConfig.cs
+++ b/src/Servers/IIS/IIS/benchmarks/IIS.Performance/FirstRequestConfig.cs
@@ -27,10 +27,10 @@ namespace BenchmarkDotNet.Attributes
 
             Add(JitOptimizationsValidator.FailOnError);
 
-            Add(Job.Core
+            Add(Job.Default
                 .With(CsProjCoreToolchain.From(NetCoreAppSettings.NetCoreApp21))
                 .With(new GcMode { Server = true })
-                .WithTargetCount(10)
+                .WithIterationCount(10)
                 .WithInvocationCount(1)
                 .WithUnrollFactor(1)
                 .With(RunStrategy.ColdStart));
diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Http2ConnectionBenchmark.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Http2ConnectionBenchmark.cs
new file mode 100644
index 00000000000..1438fb5379f
--- /dev/null
+++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Http2ConnectionBenchmark.cs
@@ -0,0 +1,101 @@
+// 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 System.Buffers;
+using System.Collections.Generic;
+using System.IO.Pipelines;
+using System.Net.Http.HPack;
+using System.Threading.Tasks;
+using BenchmarkDotNet.Attributes;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Features;
+using Microsoft.AspNetCore.Server.Kestrel.Core;
+using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
+using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
+using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2;
+using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
+using Microsoft.AspNetCore.Testing;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Primitives;
+using Microsoft.Net.Http.Headers;
+
+namespace Microsoft.AspNetCore.Server.Kestrel.Performance
+{
+    public class Http2ConnectionBenchmark
+    {
+        private MemoryPool<byte> _memoryPool;
+        private Pipe _pipe;
+        private HttpRequestHeaders _httpRequestHeaders;
+        private Http2Connection _connection;
+        private Http2HeadersEnumerator _requestHeadersEnumerator;
+        private int _currentStreamId;
+        private HPackEncoder _hpackEncoder;
+        private byte[] _headersBuffer;
+
+        [GlobalSetup]
+        public void GlobalSetup()
+        {
+            _memoryPool = SlabMemoryPoolFactory.Create();
+
+            var options = new PipeOptions(_memoryPool, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false);
+            _pipe = new Pipe(options);
+
+            _httpRequestHeaders = new HttpRequestHeaders();
+            _httpRequestHeaders.Append(HeaderNames.Method, new StringValues("GET"));
+            _httpRequestHeaders.Append(HeaderNames.Path, new StringValues("/"));
+            _httpRequestHeaders.Append(HeaderNames.Scheme, new StringValues("http"));
+            _httpRequestHeaders.Append(HeaderNames.Authority, new StringValues("localhost:80"));
+
+            _hpackEncoder = new HPackEncoder();
+            _headersBuffer = new byte[1024 * 16];
+
+            var serviceContext = new ServiceContext
+            {
+                DateHeaderValueManager = new DateHeaderValueManager(),
+                ServerOptions = new KestrelServerOptions(),
+                Log = new KestrelTrace(NullLogger.Instance),
+                SystemClock = new MockSystemClock()
+            };
+            serviceContext.ServerOptions.Limits.Http2.MaxStreamsPerConnection = int.MaxValue;
+            serviceContext.DateHeaderValueManager.OnHeartbeat(default);
+
+            _connection = new Http2Connection(new HttpConnectionContext
+            {
+                MemoryPool = _memoryPool,
+                ConnectionId = "TestConnectionId",
+                Protocols = Core.HttpProtocols.Http2,
+                Transport = new MockDuplexPipe(_pipe.Reader, new NullPipeWriter()),
+                ServiceContext = serviceContext,
+                ConnectionFeatures = new FeatureCollection(),
+                TimeoutControl = new MockTimeoutControl(),
+            });
+
+            _requestHeadersEnumerator = new Http2HeadersEnumerator();
+
+            _currentStreamId = 1;
+
+            _ = _connection.ProcessRequestsAsync(new DummyApplication());
+
+            _pipe.Writer.Write(Http2Connection.ClientPreface);
+            PipeWriterHttp2FrameExtensions.WriteSettings(_pipe.Writer, new Http2PeerSettings());
+            _pipe.Writer.FlushAsync().GetAwaiter().GetResult();
+        }
+
+        [Benchmark]
+        public async Task EmptyRequest()
+        {
+            _requestHeadersEnumerator.Initialize(_httpRequestHeaders);
+            PipeWriterHttp2FrameExtensions.WriteStartStream(_pipe.Writer, streamId: _currentStreamId, _requestHeadersEnumerator, _hpackEncoder, _headersBuffer, endStream: true);
+            _currentStreamId += 2;
+            await _pipe.Writer.FlushAsync();
+        }
+
+        [GlobalCleanup]
+        public void Dispose()
+        {
+            _pipe.Writer.Complete();
+            _memoryPool?.Dispose();
+        }
+    }
+}
diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Microsoft.AspNetCore.Server.Kestrel.Performance.csproj b/src/Servers/Kestrel/perf/Kestrel.Performance/Microsoft.AspNetCore.Server.Kestrel.Performance.csproj
index 07c9d49f68a..ef22ae3002d 100644
--- a/src/Servers/Kestrel/perf/Kestrel.Performance/Microsoft.AspNetCore.Server.Kestrel.Performance.csproj
+++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Microsoft.AspNetCore.Server.Kestrel.Performance.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
@@ -10,6 +10,8 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <Compile Include="$(KestrelSharedSourceRoot)test\DummyApplication.cs" />
+    <Compile Include="$(KestrelSharedSourceRoot)test\PipeWriterHttp2FrameExtensions.cs" />
     <Compile Include="$(RepoRoot)src\Shared\Buffers.MemoryPool\*.cs" LinkBase="MemoryPool" />
     <Compile Include="$(KestrelSharedSourceRoot)test\TestApplicationErrorLogger.cs" />
     <Compile Include="$(KestrelSharedSourceRoot)test\TestHttp1Connection.cs" />
diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockDuplexPipe.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockDuplexPipe.cs
new file mode 100644
index 00000000000..86f6dc31121
--- /dev/null
+++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockDuplexPipe.cs
@@ -0,0 +1,19 @@
+// 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.IO.Pipelines;
+
+namespace Microsoft.AspNetCore.Server.Kestrel.Performance
+{
+    internal class MockDuplexPipe : IDuplexPipe
+    {
+        public MockDuplexPipe(PipeReader input, PipeWriter output)
+        {
+            Input = input;
+            Output = output;
+        }
+
+        public PipeReader Input { get; }
+        public PipeWriter Output { get; }
+    }
+}
diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockSystemClock.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockSystemClock.cs
new file mode 100644
index 00000000000..960d2cba950
--- /dev/null
+++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockSystemClock.cs
@@ -0,0 +1,15 @@
+// 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.Server.Kestrel.Core.Internal.Infrastructure;
+
+namespace Microsoft.AspNetCore.Server.Kestrel.Performance
+{
+    internal class MockSystemClock : ISystemClock
+    {
+        public DateTimeOffset UtcNow { get; }
+        public long UtcNowTicks { get; }
+        public DateTimeOffset UtcNowUnsynchronized { get; }
+    }
+}
diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTimeoutControl.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTimeoutControl.cs
new file mode 100644
index 00000000000..54865db3c3d
--- /dev/null
+++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTimeoutControl.cs
@@ -0,0 +1,62 @@
+// 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 Microsoft.AspNetCore.Server.Kestrel.Core;
+using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.FlowControl;
+using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
+
+namespace Microsoft.AspNetCore.Server.Kestrel.Performance
+{
+    internal class MockTimeoutControl : ITimeoutControl
+    {
+        public TimeoutReason TimerReason { get; } = TimeoutReason.KeepAlive;
+
+        public void BytesRead(long count)
+        {
+        }
+
+        public void BytesWrittenToBuffer(MinDataRate minRate, long count)
+        {
+        }
+
+        public void CancelTimeout()
+        {
+        }
+
+        public void InitializeHttp2(InputFlowControl connectionInputFlowControl)
+        {
+        }
+
+        public void ResetTimeout(long ticks, TimeoutReason timeoutReason)
+        {
+        }
+
+        public void SetTimeout(long ticks, TimeoutReason timeoutReason)
+        {
+        }
+
+        public void StartRequestBody(MinDataRate minRate)
+        {
+        }
+
+        public void StartTimingRead()
+        {
+        }
+
+        public void StartTimingWrite()
+        {
+        }
+
+        public void StopRequestBody()
+        {
+        }
+
+        public void StopTimingRead()
+        {
+        }
+
+        public void StopTimingWrite()
+        {
+        }
+    }
+}
diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullPipeWriter.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullPipeWriter.cs
index 24adcba48ae..c982ec49029 100644
--- a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullPipeWriter.cs
+++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/NullPipeWriter.cs
@@ -10,7 +10,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
 {
     internal class NullPipeWriter : PipeWriter
     {
-        private byte[] _buffer = new byte[1024 * 128];
+        // Should be large enough for any content attempting to write to the buffer
+        private readonly byte[] _buffer = new byte[1024 * 128];
 
         public override void Advance(int bytes)
         {
diff --git a/src/Servers/Kestrel/shared/test/PipeWriterHttp2FrameExtensions.cs b/src/Servers/Kestrel/shared/test/PipeWriterHttp2FrameExtensions.cs
new file mode 100644
index 00000000000..beb76e1c55b
--- /dev/null
+++ b/src/Servers/Kestrel/shared/test/PipeWriterHttp2FrameExtensions.cs
@@ -0,0 +1,78 @@
+// 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 System.Buffers;
+using System.Collections.Generic;
+using System.IO.Pipelines;
+using System.Net.Http.HPack;
+using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2;
+
+namespace Microsoft.AspNetCore.Testing
+{
+    internal static class PipeWriterHttp2FrameExtensions
+    {
+        public static void WriteSettings(this PipeWriter writer, Http2PeerSettings clientSettings)
+        {
+            var frame = new Http2Frame();
+            frame.PrepareSettings(Http2SettingsFrameFlags.NONE);
+            var settings = clientSettings.GetNonProtocolDefaults();
+            var payload = new byte[settings.Count * Http2FrameReader.SettingSize];
+            frame.PayloadLength = payload.Length;
+            Http2FrameWriter.WriteSettings(settings, payload);
+            Http2FrameWriter.WriteHeader(frame, writer);
+            writer.Write(payload);
+        }
+
+        public static void WriteStartStream(this PipeWriter writer, int streamId, Http2HeadersEnumerator headers, HPackEncoder hpackEncoder, byte[] headerEncodingBuffer, bool endStream)
+        {
+            var frame = new Http2Frame();
+            frame.PrepareHeaders(Http2HeadersFrameFlags.NONE, streamId);
+
+            var buffer = headerEncodingBuffer.AsSpan();
+            var done = hpackEncoder.BeginEncode(headers, buffer, out var length);
+            frame.PayloadLength = length;
+
+            if (done)
+            {
+                frame.HeadersFlags = Http2HeadersFrameFlags.END_HEADERS;
+            }
+
+            if (endStream)
+            {
+                frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
+            }
+
+            Http2FrameWriter.WriteHeader(frame, writer);
+            writer.Write(buffer.Slice(0, length));
+
+            while (!done)
+            {
+                frame.PrepareContinuation(Http2ContinuationFrameFlags.NONE, streamId);
+
+                done = hpackEncoder.Encode(buffer, out length);
+                frame.PayloadLength = length;
+
+                if (done)
+                {
+                    frame.ContinuationFlags = Http2ContinuationFrameFlags.END_HEADERS;
+                }
+
+                Http2FrameWriter.WriteHeader(frame, writer);
+                writer.Write(buffer.Slice(0, length));
+            }
+        }
+
+        public static void WriteData(this PipeWriter writer, int streamId, Memory<byte> data, bool endStream)
+        {
+            var frame = new Http2Frame();
+
+            frame.PrepareData(streamId);
+            frame.PayloadLength = data.Length;
+            frame.DataFlags = endStream ? Http2DataFrameFlags.END_STREAM : Http2DataFrameFlags.NONE;
+
+            Http2FrameWriter.WriteHeader(frame, writer);
+            writer.Write(data.Span);
+        }
+    }
+}
diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs
index de1a57beb29..68076af39ce 100644
--- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs
+++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs
@@ -501,56 +501,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
             var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
             _runningStreams[streamId] = tcs;
 
-            var frame = new Http2Frame();
-            frame.PrepareHeaders(Http2HeadersFrameFlags.NONE, streamId);
-
-            var buffer = _headerEncodingBuffer.AsSpan();
-            var done = _hpackEncoder.BeginEncode(GetHeadersEnumerator(headers), buffer, out var length);
-            frame.PayloadLength = length;
-
-            if (done)
-            {
-                frame.HeadersFlags = Http2HeadersFrameFlags.END_HEADERS;
-            }
-
-            if (endStream)
-            {
-                frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
-            }
-
-            Http2FrameWriter.WriteHeader(frame, writableBuffer);
-            writableBuffer.Write(buffer.Slice(0, length));
-
-            while (!done)
-            {
-                frame.PrepareContinuation(Http2ContinuationFrameFlags.NONE, streamId);
-
-                done = _hpackEncoder.Encode(buffer, out length);
-                frame.PayloadLength = length;
-
-                if (done)
-                {
-                    frame.ContinuationFlags = Http2ContinuationFrameFlags.END_HEADERS;
-                }
-
-                Http2FrameWriter.WriteHeader(frame, writableBuffer);
-                writableBuffer.Write(buffer.Slice(0, length));
-            }
-
+            PipeWriterHttp2FrameExtensions.WriteStartStream(writableBuffer, streamId, GetHeadersEnumerator(headers), _hpackEncoder, _headerEncodingBuffer, endStream);
             return FlushAsync(writableBuffer);
         }
 
-        private static Http2HeadersEnumerator GetHeadersEnumerator(IEnumerable<KeyValuePair<string, string>> headers)
-        {
-            var groupedHeaders = headers
-                .GroupBy(k => k.Key)
-                .ToDictionary(g => g.Key, g => new StringValues(g.Select(gg => gg.Value).ToArray()));
-
-            var enumerator = new Http2HeadersEnumerator();
-            enumerator.Initialize(groupedHeaders);
-            return enumerator;
-        }
-
         /* https://tools.ietf.org/html/rfc7540#section-6.2
             +---------------+
             |Pad Length? (8)|
@@ -704,15 +658,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
 
         protected async Task SendSettingsAsync()
         {
-            var writableBuffer = _pair.Application.Output;
-            var frame = new Http2Frame();
-            frame.PrepareSettings(Http2SettingsFrameFlags.NONE);
-            var settings = _clientSettings.GetNonProtocolDefaults();
-            var payload = new byte[settings.Count * Http2FrameReader.SettingSize];
-            frame.PayloadLength = payload.Length;
-            Http2FrameWriter.WriteSettings(settings, payload);
-            Http2FrameWriter.WriteHeader(frame, writableBuffer);
-            await SendAsync(payload);
+            PipeWriterHttp2FrameExtensions.WriteSettings(_pair.Application.Output, _clientSettings);
+            await FlushAsync(_pair.Application.Output);
         }
 
         protected async Task SendSettingsAckWithInvalidLengthAsync(int length)
@@ -890,6 +837,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
             return done;
         }
 
+        private Http2HeadersEnumerator GetHeadersEnumerator(IEnumerable<KeyValuePair<string, string>> headers)
+        {
+            var dictionary = headers
+                .GroupBy(g => g.Key)
+                .ToDictionary(g => g.Key, g => new StringValues(g.Select(values => values.Value).ToArray()));
+
+            var headersEnumerator = new Http2HeadersEnumerator();
+            headersEnumerator.Initialize(dictionary);
+            return headersEnumerator;
+        }
+
         internal Task SendEmptyContinuationFrameAsync(int streamId, Http2ContinuationFrameFlags flags)
         {
             var outputWriter = _pair.Application.Output;
@@ -923,14 +881,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
         protected Task SendDataAsync(int streamId, Memory<byte> data, bool endStream)
         {
             var outputWriter = _pair.Application.Output;
-            var frame = new Http2Frame();
-
-            frame.PrepareData(streamId);
-            frame.PayloadLength = data.Length;
-            frame.DataFlags = endStream ? Http2DataFrameFlags.END_STREAM : Http2DataFrameFlags.NONE;
-
-            Http2FrameWriter.WriteHeader(frame, outputWriter);
-            return SendAsync(data.Span);
+            PipeWriterHttp2FrameExtensions.WriteData(outputWriter, streamId, data, endStream);
+            return FlushAsync(outputWriter);
         }
 
         protected async Task SendDataWithPaddingAsync(int streamId, Memory<byte> data, byte padLength, bool endStream)
diff --git a/src/Shared/BenchmarkRunner/DefaultCoreConfig.cs b/src/Shared/BenchmarkRunner/DefaultCoreConfig.cs
index 0691936c354..e5b0c9b43b8 100644
--- a/src/Shared/BenchmarkRunner/DefaultCoreConfig.cs
+++ b/src/Shared/BenchmarkRunner/DefaultCoreConfig.cs
@@ -27,7 +27,7 @@ namespace BenchmarkDotNet.Attributes
 
             Add(JitOptimizationsValidator.FailOnError);
 
-            Add(Job.Core
+            Add(Job.Default
 #if NETCOREAPP2_1
                 .With(CsProjCoreToolchain.From(NetCoreAppSettings.NetCoreApp21))
 #elif NETCOREAPP3_0
diff --git a/src/Shared/BenchmarkRunner/DefaultCorePerfLabConfig.cs b/src/Shared/BenchmarkRunner/DefaultCorePerfLabConfig.cs
index 5cc809e1661..5c6ba7ac3b8 100644
--- a/src/Shared/BenchmarkRunner/DefaultCorePerfLabConfig.cs
+++ b/src/Shared/BenchmarkRunner/DefaultCorePerfLabConfig.cs
@@ -22,10 +22,7 @@ namespace BenchmarkDotNet.Attributes
             Add(MemoryDiagnoser.Default);
             Add(StatisticColumn.OperationsPerSecond);
             Add(new ParamsSummaryColumn());
-            Add(DefaultColumnProviders.Statistics, DefaultColumnProviders.Diagnosers, DefaultColumnProviders.Target);
-
-            // TODO: When upgrading to BDN 0.11.1, use Add(DefaultColumnProviders.Descriptor); 
-            // DefaultColumnProviders.Target is deprecated
+            Add(DefaultColumnProviders.Statistics, DefaultColumnProviders.Metrics, DefaultColumnProviders.Descriptor);
 
             Add(JitOptimizationsValidator.FailOnError);
 
@@ -36,13 +33,7 @@ namespace BenchmarkDotNet.Attributes
 
             Add(new CsvExporter(
                 CsvSeparator.Comma,
-                new Reports.SummaryStyle
-                {
-                    PrintUnitsInHeader = true,
-                    PrintUnitsInContent = false,
-                    TimeUnit = Horology.TimeUnit.Microsecond,
-                    SizeUnit = SizeUnit.KB
-                }));
+                new Reports.SummaryStyle(printUnitsInHeader: true, printUnitsInContent: false, timeUnit: Horology.TimeUnit.Microsecond, sizeUnit: SizeUnit.KB)));
         }
     }
 }
diff --git a/src/Shared/BenchmarkRunner/DefaultCoreValidationConfig.cs b/src/Shared/BenchmarkRunner/DefaultCoreValidationConfig.cs
index 5a90929cff8..3faf5ac1cb7 100644
--- a/src/Shared/BenchmarkRunner/DefaultCoreValidationConfig.cs
+++ b/src/Shared/BenchmarkRunner/DefaultCoreValidationConfig.cs
@@ -4,7 +4,7 @@
 using BenchmarkDotNet.Configs;
 using BenchmarkDotNet.Jobs;
 using BenchmarkDotNet.Loggers;
-using BenchmarkDotNet.Toolchains.InProcess;
+using BenchmarkDotNet.Toolchains.InProcess.NoEmit;
 
 namespace BenchmarkDotNet.Attributes
 {
@@ -14,7 +14,7 @@ namespace BenchmarkDotNet.Attributes
         {
             Add(ConsoleLogger.Default);
 
-            Add(Job.Dry.With(InProcessToolchain.Instance));
+            Add(Job.Dry.With(InProcessNoEmitToolchain.Instance));
         }
     }
 }
diff --git a/src/Shared/BenchmarkRunner/ParamsDisplayInfoColumn.cs b/src/Shared/BenchmarkRunner/ParamsDisplayInfoColumn.cs
index b246e21c2e2..2267de01a68 100644
--- a/src/Shared/BenchmarkRunner/ParamsDisplayInfoColumn.cs
+++ b/src/Shared/BenchmarkRunner/ParamsDisplayInfoColumn.cs
@@ -11,8 +11,8 @@ namespace BenchmarkDotNet.Attributes
     {
         public string Id => nameof(ParamsSummaryColumn);
         public string ColumnName { get; } = "Params";
-        public bool IsDefault(Summary summary, Benchmark benchmark) => false;
-        public string GetValue(Summary summary, Benchmark benchmark) => benchmark.Parameters.DisplayInfo;
+        public bool IsDefault(Summary summary, BenchmarkCase benchmark) => false;
+        public string GetValue(Summary summary, BenchmarkCase benchmark) => benchmark.Parameters.DisplayInfo;
         public bool IsAvailable(Summary summary) => true;
         public bool AlwaysShow => true;
         public ColumnCategory Category => ColumnCategory.Params;
@@ -20,7 +20,7 @@ namespace BenchmarkDotNet.Attributes
         public override string ToString() => ColumnName;
         public bool IsNumeric => false;
         public UnitType UnitType => UnitType.Dimensionless;
-        public string GetValue(Summary summary, Benchmark benchmark, ISummaryStyle style) => GetValue(summary, benchmark);
+        public string GetValue(Summary summary, BenchmarkCase benchmark, SummaryStyle style) => GetValue(summary, benchmark);
         public string Legend => $"Summary of all parameter values";
     }
-}
\ No newline at end of file
+}
-- 
GitLab