From f346110a8af9b42de7b2d094d33a6e13cb8cfccb Mon Sep 17 00:00:00 2001 From: gewuyou <95328647+GeWuYou@users.noreply.github.com> Date: Tue, 12 May 2026 13:17:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(cqrs-benchmarks):=20=E8=A1=A5=E9=BD=90=20s?= =?UTF-8?q?tream=20startup=20=E7=9A=84=20Mediator=20=E5=AF=B9=E7=85=A7?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 StreamStartupBenchmarks 的 Mediator 初始化与 cold-start benchmark。 - 更新 stream request 与 handler 契约以接入 NuGet Mediator source-generated concrete path。 --- .../Messaging/StreamStartupBenchmarks.cs | 60 +++++++++++++++++-- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/GFramework.Cqrs.Benchmarks/Messaging/StreamStartupBenchmarks.cs b/GFramework.Cqrs.Benchmarks/Messaging/StreamStartupBenchmarks.cs index 26947bbd..29a5cfb8 100644 --- a/GFramework.Cqrs.Benchmarks/Messaging/StreamStartupBenchmarks.cs +++ b/GFramework.Cqrs.Benchmarks/Messaging/StreamStartupBenchmarks.cs @@ -19,6 +19,7 @@ using GFramework.Core.Logging; using GFramework.Cqrs.Abstractions.Cqrs; using MediatR; using Microsoft.Extensions.DependencyInjection; +using GeneratedMediator = Mediator.Mediator; [assembly: GFramework.Cqrs.CqrsHandlerRegistryAttribute( typeof(GFramework.Cqrs.Benchmarks.Messaging.StreamStartupBenchmarks.GeneratedRegistry))] @@ -26,7 +27,7 @@ using Microsoft.Extensions.DependencyInjection; namespace GFramework.Cqrs.Benchmarks.Messaging; /// -/// 对比 stream 宿主在 GFramework.CQRS reflection / generated 与 MediatR 之间的初始化与首次建流命中成本。 +/// 对比 stream 宿主在 GFramework.CQRS reflection / generated、NuGet `Mediator` 与 MediatR 之间的初始化与首次建流命中成本。 /// /// /// 该场景与 保持相同的 `Initialization + ColdStart` 结构, @@ -45,7 +46,9 @@ public class StreamStartupBenchmarks private MicrosoftDiContainer _generatedContainer = null!; private ICqrsRuntime _generatedRuntime = null!; private ServiceProvider _serviceProvider = null!; + private ServiceProvider _mediatorServiceProvider = null!; private IMediator _mediatr = null!; + private GeneratedMediator _mediator = null!; /// /// 配置 stream startup benchmark 的公共输出格式。 @@ -67,7 +70,7 @@ public class StreamStartupBenchmarks } /// - /// 构建 startup benchmark 复用的 reflection / generated / MediatR 宿主对象。 + /// 构建 startup benchmark 复用的 reflection / generated / `Mediator` / MediatR 宿主对象。 /// [GlobalSetup] public void Setup() @@ -82,6 +85,8 @@ public class StreamStartupBenchmarks _serviceProvider = CreateMediatRServiceProvider(); _mediatr = _serviceProvider.GetRequiredService(); + _mediatorServiceProvider = CreateMediatorServiceProvider(); + _mediator = _mediatorServiceProvider.GetRequiredService(); } /// @@ -99,7 +104,7 @@ public class StreamStartupBenchmarks [GlobalCleanup] public void Cleanup() { - BenchmarkCleanupHelper.DisposeAll(_reflectionContainer, _generatedContainer, _serviceProvider); + BenchmarkCleanupHelper.DisposeAll(_reflectionContainer, _generatedContainer, _serviceProvider, _mediatorServiceProvider); } /// @@ -135,6 +140,17 @@ public class StreamStartupBenchmarks return _generatedRuntime; } + /// + /// 返回已构建宿主中的 `Mediator` concrete mediator,作为 source-generated concrete path 的初始化句柄。 + /// + /// 当前 benchmark 复用的 `Mediator` concrete mediator。 + [Benchmark] + [BenchmarkCategory("Initialization")] + public GeneratedMediator Initialization_Mediator() + { + return _mediator; + } + /// /// 在新宿主上首次创建并推进 stream,作为 MediatR 的 cold-start baseline。 /// @@ -180,6 +196,19 @@ public class StreamStartupBenchmarks .ConfigureAwait(false); } + /// + /// 在新的 `Mediator` 宿主上首次创建并推进 stream,量化 source-generated concrete path 的 first-hit 成本。 + /// + /// 首个 stream 响应元素。 + [Benchmark] + [BenchmarkCategory("ColdStart")] + public async ValueTask ColdStart_Mediator() + { + using var serviceProvider = CreateMediatorServiceProvider(); + var mediator = serviceProvider.GetRequiredService(); + return await ConsumeFirstItemAsync(mediator.CreateStream(Request, CancellationToken.None), CancellationToken.None).ConfigureAwait(false); + } + /// /// 构建只承载当前 benchmark handler 的最小 reflection GFramework.CQRS 容器。 /// @@ -229,6 +258,14 @@ public class StreamStartupBenchmarks ServiceLifetime.Transient); } + /// + /// 构建只承载当前 benchmark handler 的最小 `Mediator` 对照宿主。 + /// + private static ServiceProvider CreateMediatorServiceProvider() + { + return BenchmarkHostFactory.CreateMediatorServiceProvider(configure: null); + } + /// /// 推进 stream 到首个元素,并返回该元素作为 cold-start 结果。 /// @@ -274,6 +311,7 @@ public class StreamStartupBenchmarks /// 返回元素数量。 public sealed record BenchmarkStreamRequest(Guid Id, int ItemCount) : GFramework.Cqrs.Abstractions.Cqrs.IStreamRequest, + Mediator.IStreamRequest, MediatR.IStreamRequest; /// @@ -283,10 +321,11 @@ public class StreamStartupBenchmarks public sealed record BenchmarkResponse(Guid Id); /// - /// 同时实现 GFramework.CQRS 与 MediatR 契约的最小 stream handler。 + /// 同时实现 GFramework.CQRS、NuGet `Mediator` 与 MediatR 契约的最小 stream handler。 /// public sealed class BenchmarkStreamHandler : GFramework.Cqrs.Abstractions.Cqrs.IStreamRequestHandler, + Mediator.IStreamRequestHandler, MediatR.IStreamRequestHandler { /// @@ -302,6 +341,19 @@ public class StreamStartupBenchmarks return EnumerateAsync(request, cancellationToken); } + /// + /// 处理 NuGet `Mediator` stream request。 + /// + /// 当前 stream 请求。 + /// 用于中断异步枚举的取消令牌。 + /// 按请求元素数量延迟生成的异步响应序列。 + IAsyncEnumerable Mediator.IStreamRequestHandler.Handle( + BenchmarkStreamRequest request, + CancellationToken cancellationToken) + { + return Handle(request, cancellationToken); + } + /// /// 处理 MediatR stream request。 ///