Skip to content

Match PerformanceStudio's runtime summary card: title, order, memory-grant colors, spill flag - #4590

Merged
erikdarlingdata merged 7 commits into
devfrom
viewer/4570-runtime-card
Sep 28, 2026
Merged

erikdarlingdata merged 7 commits into
devfrom
viewer/4570-runtime-card

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Fixes #4570. Part of #4511. The CPU:Elapsed row came with #4565.

Why

PerformanceStudio's Avalonia plan viewer (erikdarlingdata/PerformanceStudio@40ade29, superseding @5731ae9) changed its runtime summary card in four ways the shared PM/Lite viewer didn't have: the card's title becomes "Predicted Runtime" for a statement with no runtime stats (estimated-plan-only); the memory grant row is colored by utilization, with an over-used grant (>100%) always red and any spilled operator anywhere in the plan forcing at least the warning tier plus a "⚠ spill" suffix; the efficiency thresholds used for memory grant / DOP / thread utilization loosened from the old ≥80/≥60/≥40 tiers to ≥40 (default) / ≥20 (warning) / <20 (error); and the row order changed to Elapsed → CPU:Elapsed → DOP → CPU → Compile → Memory grant → Optimization → CE model.

What changes

  • PerformanceMonitor.PlanAnalysis/PlanDisplayText.cs: five new pure, pinned helpers plus a RuntimeSummaryRow record:
    • RuntimeSummaryTitle(statement) — "Predicted Runtime" vs "Runtime Summary".
    • HasSpillInPlanTree(node) — recursive walk for any warning type ending in " Spill".
    • EfficiencyColorKey(pct) — the ≥40/≥20/<20 tiers (used for DOP and thread efficiency; null means the card's default value color).
    • MemoryGrantColorKey(pctUsed, hasSpill) — >100% is always the error tier; a plan-wide spill forces at least the warning tier; otherwise follows EfficiencyColorKey.
    • BuildRuntimeSummaryRows(statement): the whole card's row list in PerformanceStudio's order, as a pure function a test can call directly. PerformanceStudio's desktop viewer builds its runtime summary rows directly, with no equivalent extra-rows parameter, and so does this.
  • PerformanceMonitor.Ui/PlanViewerControl.Properties.cs: ShowRuntimeSummary now sets the title from PlanDisplayText.RuntimeSummaryTitle and builds its rows entirely from PlanDisplayText.BuildRuntimeSummaryRows, applying each row's ColorKey as a theme brush resource lookup (ErrorBrush/WarningBrush/default). The old inline FormatMemoryGrantKB moved into the shared helper (used internally by BuildRuntimeSummaryRows); the WPF file no longer needs its own copy.
  • PerformanceMonitor.Ui/PlanViewerControl.xaml: the static "Runtime Summary" TextBlock gets x:Name="RuntimeSummaryTitle" so the code-behind can swap its text.

Lite: gets this too (shared control — PlanViewerControl is hosted by both the Darling Viewer and Lite; no Lite-specific code changed).

PM-ahead: none noted for this card.

Test plan

New pins: Darling/Darling.Tests/Viewer4570Tests.cs, 22 facts/theories covering the title swap, the spill-tree walk (null root, no warnings, non-spill warning, root warning, warning deep in a child), the efficiency threshold boundaries (100/40/39.9/20/19.9/0), the memory-grant color combinations (over-used with/without spill, high utilization with/without spill, low utilization), the actual-plan row order, the estimated-plan row omissions, the memory-grant row's color/spill-tag, and compile time always showing.

RED on the base branch (plan-sync/4537-drop-rules @ a38f81d): all five helpers plus RuntimeSummaryRow are new, so the test file fails to compile there (CS0117/CS0246 on every reference) — a labelled compile-only RED, since every helper is new.

Mutation (runtime RED, not just compile-fail): changed EfficiencyColorKey's thresholds from pct >= 40 ... pct >= 20 to pct >= 80 ... pct >= 60. Result: 4 of 23 facts failed (MemoryGrantColorKey_HighUtilizationNoSpill_IsDefault, and the three EfficiencyColorKey_MatchesPsThresholds boundary cases at 40/39.9/20). Reverted; rebuilt; all 23 pass again (Total: 23, Errors: 0, Failed: 0).

Full run (built Darling.Tests, PerformanceMonitor.Ui, Lite/PerformanceMonitorLite.csproj, Darling/PerformanceMonitor.Darling.Viewer Release with -p:EnableWindowsTargeting=true, all 0 warnings/0 errors): Viewer4570Tests plus every required Viewer*/PlanSync*/plan-analysis pipeline class → Total: 253, Errors: 0, Failed: 0, Skipped: 1, Not Run: 0. (The one skip is DarlingMcpPlanToolsLivePostgresTests, which needs a live Postgres rig not available here; unrelated to this change.)

Lite.Tests and Lite/PerformanceMonitorLite.csproj: build-only on this machine (net10.0-windows can't execute Lite.Tests here); no Lite-specific code changed by this PR, so no new Lite pin is needed — CI decides the Windows-only run.

Screenshot plan: open any actual plan with a memory grant in the Darling Viewer or Lite. Expect: card titled "Runtime Summary"; rows in order Elapsed, CPU:Elapsed, DOP, CPU, Compile, Memory grant, Optimization, CE model (only the ones the plan has data for); the Memory grant row's value colored red if used% > 100, orange (warning) if any operator spilled or utilization is 20-39%, default color otherwise, with "⚠ spill" appended when any operator spilled. Open an estimated-only plan (no runtime stats): the same card's title reads "Predicted Runtime".

CHANGELOG

SECTION: Changed
ENTRY: - The plan viewer's runtime summary card matches PerformanceStudio's ([#4590]) - It's titled "Predicted Runtime" for an estimated-only plan, rows are reordered (Elapsed, CPU:Elapsed, DOP, CPU, Compile, Memory grant, Optimization, CE model), the memory grant row is colored by utilization (red over 100% used, orange when any operator spilled or utilization is moderate-low, red when utilization is very low) with a "⚠ spill" tag when any operator in the plan spilled, and compile time is always shown.
REF: [#4590]: #4590

erikdarlingdata and others added 7 commits September 28, 2026 09:01
…ism and Parallel Wait Bottleneck rules, matching PerformanceStudio (#4537)

Rule 21 (CTE Multiple References) guessed at CTE reuse from statement text; an actual plan's own runtime stats already show where time went. Rules 25 (Ineffective Parallelism) and 31 (Parallel Wait Bottleneck) guessed at parallelism efficiency causes that the wait stats list and the runtime summary's new CPU:Elapsed ratio already show directly.
… PerformanceStudio's

Moved the CPU:Elapsed row so it sits right after Elapsed, and made its
CPU value subtract external-wait time before dividing, matching
erikdarlingdata/PerformanceStudio@28d4c74. The ratio is now computed
by a small pure helper (PlanDisplayText.CpuElapsedRatio) so it can be
pinned without a WPF host.
Adds back the three rule-removal tests (CTE Multiple References,
Parallel Wait Bottleneck, Ineffective Parallelism) alongside the four
CPU:Elapsed ratio tests, so all seven pins for this change live in one
class.
# Conflicts:
#	PerformanceMonitor.PlanAnalysis/PlanDisplayText.cs
#	PerformanceMonitor.Ui/PlanViewerControl.Properties.cs
…maryRows

The runtime summary card has no source that supplies extra memory
grant rows today, so the parameter and its pin are dead. PerformanceStudio's
desktop plan viewer builds its runtime summary rows directly, with no
equivalent extra-rows input.
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review September 28, 2026 15:27
@erikdarlingdata
erikdarlingdata merged commit 6e59c67 into dev Sep 28, 2026
18 of 20 checks passed
@erikdarlingdata
erikdarlingdata deleted the viewer/4570-runtime-card branch September 28, 2026 15:27
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