Skip to content

Flush output only at outer render boundaries - #978

Closed
sebastienros wants to merge 1 commit into
mainfrom
sebros/flush-outer-render-boundary
Closed

Flush output only at outer render boundaries#978
sebastienros wants to merge 1 commit into
mainfrom
sebros/flush-outer-render-boundary

Conversation

@sebastienros

Copy link
Copy Markdown
Owner

Summary

  • add an internal no-flush rendering path for parsed and composite templates while preserving the public IFluidTemplate.RenderAsync(IFluidOutput, ...) flush contract
  • route nested render, render for, and include operations through the no-flush path; source-generated child templates use an equivalent generated core
  • keep MaxOutputSize cumulative by establishing the LimitedFluidOutput once at public extension boundaries
  • add targeted flush-count, cumulative-limit, source-generation tests, and a focused BenchmarkDotNet benchmark

Benchmark

BenchmarkDotNet 0.15.8 ShortRun, .NET 10.0.10, Apple M4 Pro. The benchmark uses a reusable counting IFluidOutput; allocations are unchanged.

Scenario Before After Change Flushes before → after Allocated
one nested render 162.9 ns 171.2 ns +5.1% 2 → 1 472 B → 472 B
render for (100 items) 3,252.7 ns 3,220.5 ns -1.0% 101 → 1 496 B → 496 B

The no-op counting output intentionally understates the benefit for streaming outputs where each flush performs I/O. The single-child result is slightly slower; the loop workload improves while eliminating 100 output-boundary operations.

Command:

RestoreSources=https://packagefeedproxy.microsoft.io/nuget/v3/index.json dotnet run -c Release --no-restore --project Fluid.Benchmarks -- --filter '*NestedRenderBenchmarks*' --job short

Generated BenchmarkDotNet artifacts were not committed.

Validation

  • targeted flush tests, interpreted and /p:Compiled=true: 5 passed in each mode
  • dotnet test --no-restore: 2,750 passed, 20 skipped
  • dotnet test --no-restore /p:Compiled=true: 2,750 passed, 20 skipped
  • dotnet build Fluid/Fluid.csproj -c Release --no-restore: all target frameworks passed, including netstandard2.0

The required NuGet proxy did not yet contain pinned xunit.v3.mtp-v2 4.0.0, so local test restore used the proxy's nearest 4.0.0-pre.154 via an external temporary MSBuild props file. No feed or dependency changes were written to the repository.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@sebastienros

Copy link
Copy Markdown
Owner Author

Closing because this performance work is investigatory only; the benchmark branch remains available.

@sebastienros
sebastienros deleted the sebros/flush-outer-render-boundary branch August 18, 2026 18:30
@sebastienros
sebastienros restored the sebros/flush-outer-render-boundary branch August 19, 2026 03:20
@sebastienros
sebastienros deleted the sebros/flush-outer-render-boundary branch August 19, 2026 04:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant