Skip to content

PR-L2 — S-98 inter-product rules (R-101-102, R-101-124, R-104, R-111)#119

Merged
philliphoff merged 1 commit into
mainfrom
philliphoff/pr-l2-s98-inter-product-rules
May 20, 2026
Merged

PR-L2 — S-98 inter-product rules (R-101-102, R-101-124, R-104, R-111)#119
philliphoff merged 1 commit into
mainfrom
philliphoff/pr-l2-s98-inter-product-rules

Conversation

@philliphoff
Copy link
Copy Markdown
Owner

Implements the five v1 inter-product rules from docs/design/s98-interoperability.md §3 on top of PR-L1's plane-assignment plumbing.

Rules delivered

Rule Level Effect Spec
R-101-102-A 1 S-102 between S-101 area fills and line work S-98 Main §9.2.1
R-101-102-B 2 Suppress S-101 DepthArea + DepthContour when S-102 loaded and active (with safety-contour exception) Annex A §8.4.1, Part B §B-3.1.2, MSC.232(82) §5.8
R-101-124-A 0 S-124 on CautionsAndWarnings Main §9.2.1, MSC.530(106)/Rev.1
R-104-A 1 S-104 on OnDemandSurface Annex A §A-6.9.1, Main §9.2.1 layer 6
R-111-A 1 S-111 band on OnDemandSurface, arrows on DynamicArrows Annex A §A-6.9.1

Four of the five are pure plane-order properties satisfied by PR-L1's default plane table; this PR pins them via tests. R-101-102-B is the only mutating rule.

Suppression strategy: option (b) — feature-tag filtering

I chose option (b) (filter IFeatures by tag) over option (a) (re-run the portrayal pipeline with a suppression set) because:

  • S101DatasetProcessor already maintains a lazy _featureIndex mapping FeatureRefFeature. Tagging the emitted IFeatures with their feature-type code is one dictionary lookup per feature; no pipeline change.
  • Option (a) would require re-rendering the entire ENC cell every time the loaded-dataset set changes (or every render). The briefing's perf-risk caveat about caching the rebuild becomes moot under (b).
  • The rule effect builds a new MemoryLayer per affected S-101 entry, copying only surviving features. No per-feature plane metadata is introduced (TBD-5 stays out of scope).

The R-101-102-B effect honours the MSC.232(82) §5.8 safety-contour exception: any DepthContour whose valueOfDepthContour matches the current mariner SafetyContour (tolerance 1e-6) is retained even when others are suppressed.

Wiring

  • S98InteroperabilityRule is a record (RuleId, SpecCitation, Condition, Effect) — no DSL, no Part-16 dependency. Predicates and effects are plain delegates.
  • S98DefaultRules.Default holds the five rules in declaration order (rules run in that order; pinned by Default_rule_set_is_in_documented_order test).
  • IInteroperabilityAuthority.ApplyRules(stack, loadedDatasets, mariner?, rules?) added; LoadOrderInteroperabilityAuthority returns the stack untouched.
  • DatasetLoaderService.FlattenLayerOrder calls ApplyRules after LayerStackBuilder.Build.
  • LoadedDatasetInfo.Active maps 1:1 to entry.IsVisible && layers.Count > 0 per briefing — real active/inactive lands with PR-L3 (Layer Controls UI).

TODO PR-L2-RESYNC markers

Every IC element name introduced in this PR carries the resync marker so a future S-100 Part 16 sync can find them by grep -r "TODO PR-L2-RESYNC":

  • All 5 rule declarations in S98DefaultRules.cs (rule IDs)
  • The suppressed-feature-type set inside SuppressS101DepthFeatures

Tests

  • S98DefaultRulesTests.cs (Pipelines, 11 tests): plane-order property for all four anchor rules; R-101-102-B suppression on/off; safety-contour exception; Active flag honoured; rule composition declaration order; empty rule set is a no-op; Default ordering pin.
  • PickServiceTests.cs (Viewer, +1 test): HandlePick_AfterR_101_102_B_Suppression_ReturnsS102Hit verifies picks over a suppressed DepthArea resolve to the S-102 hit.
  • Full suite: 0 failures, 280 viewer / 340 pipelines / all others passing.

Visual regression

No snapshots rebaselined. Verified there are no existing fixtures that load S-101 + S-102 together; the new rule's first opportunity to affect rendered output is when such a fixture is added.

Out of scope (per briefing)

  • IC XML rule pack under content/S98/ (lands when Part 16 is in hand — PR-L2a).
  • Per-feature plane metadata (Annex A §4.3) — TBD-5.
  • Layer Controls UI (PR-L3), PdC picker UX, IC validation against Part 16 XSD.

Refs: #117 (PR-L0 design note), #118 (PR-L1 plumbing).

Adds the five v1 inter-product rules from docs/design/s98-interoperability.md §3
on top of PR-L1's plane-assignment plumbing:

* R-101-102-A — S-102 sits between S-101 area fills and line work
  (plane-order property, no mutation).
* R-101-102-B — when an S-102 dataset is loaded and active, suppress
  S-101 DepthArea and DepthContour features (cites Annex A §8.4.1 +
  Part B §B-3.1.2). The MSC.232(82) §5.8 safety-contour exception
  retains any DepthContour whose VALDCO matches the active mariner
  safety contour (tolerance 1e-6).
* R-101-124-A — S-124 on CautionsAndWarnings (plane-order property).
* R-104-A — S-104 on OnDemandSurface (plane-order property).
* R-111-A — S-111 colour band on OnDemandSurface, arrows on
  DynamicArrows (plane-order property).

Implementation notes
--------------------
* New types in src/EncDotNet.S100.Datasets.Pipelines/Interoperability/:
  LoadedDatasetInfo, S98RuleContext, S98InteroperabilityRule (record),
  FeatureTagKeys, S98DefaultRules (static, declaration-ordered).
* IInteroperabilityAuthority gains ApplyRules(stack, loaded, mariner?,
  rules?). Default impl runs rules in declaration order; load-order
  authority is a no-op.
* DatasetLoaderService.FlattenLayerOrder now calls ApplyRules after
  LayerStackBuilder.Build, passing the current mariner settings.

Suppression strategy: option (b) — feature-tag filtering. S101DatasetProcessor
tags every Mapsui IFeature with its S-100 feature-type code (and VALDCO
for DepthContour) using the lazy _featureIndex it already maintains.
The R-101-102-B effect builds a new MemoryLayer per affected S-101 entry
with the offending features filtered out. No portrayal re-run; no per-feature
plane metadata (TBD-5 stays out of scope per briefing).

LoadedDatasetInfo.Active maps 1:1 to entry.IsVisible && layers.Count > 0
for this PR (briefing decision: 'loaded == active'; real active/inactive
arrives with Layer Controls UI in PR-L3).

Every IC element name introduction carries a // TODO PR-L2-RESYNC:
confirm against S-100 Part 16 XSD marker (briefing TBD-1).

Tests
-----
* tests/EncDotNet.S100.Pipelines.Tests/S98DefaultRulesTests.cs — 11
  tests covering: plane-order property for all four anchor rules,
  R-101-102-B suppression on/off, safety-contour exception, Active
  flag honoured, rule composition declaration order, empty rule
  set is a no-op, Default ordering pin.
* tests/EncDotNet.S100.Viewer.Tests/PickServiceTests.cs — adds
  HandlePick_AfterR_101_102_B_Suppression_ReturnsS102Hit verifying
  picks over a suppressed DepthArea resolve to the S-102 hit.

Snapshots
---------
No visual-regression snapshots changed — no existing fixture loads
S-101 and S-102 together.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

Performance Gate

PASSED — no regressions.

Threshold: 10.0%, MAD multiplier (k): 3.0, retry-zone mult: 2.0×

Scenario summary

Scenario Status Δ median (%) z (Δ/MAD) Base median (ms) Samples (b/c)
exchange-set-open ✅ pass +11.9 +1.46 0.56 20/20
s101-portray-cold ✅ pass +2.0 +1.24 318.47 20/20
s101-portray-warm ✅ pass -24.9 -1.50 160.41 20/20
s101-render-warm ✅ pass -43.3 -6.57 169.63 20/20
s102-coverage ✅ pass -1.9 -1.35 1.55 20/20
s102-coverage-open ✅ pass -4.7 -3.44 2.87 20/20
s102-coverage-render-large ✅ pass -1.0 -0.81 140.87 20/20
s124-vector ✅ pass +5.9 +2.04 0.47 20/20
s201-vector ✅ pass +2.1 +0.20 0.37 20/20

exchange-set-open

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 0.56 0.63
Baseline MAD (ms) 0.05
Δ median +11.9%
z (Δ/MAD) +1.46

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.asset.read 10.07 10.98 +9.0%
s100.exchangeset.parse 40.86 41.42 +1.4% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.asset.read.duration 18.23 18.24 +0.0% ▫️

s101-portray-cold

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 318.47 324.93
Baseline MAD (ms) 5.22
Δ median +2.0%
z (Δ/MAD) +1.24

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.lua.execute 4303.70 4451.41 +3.4% ▫️
s100.lua.rule.invoke 3572.62 3706.68 +3.8% ▫️
s100.pipeline.vector.process 4373.90 4521.24 +3.4% ▫️
s100.pipeline.vector.stage.assemble 0.24 0.25 +2.0% ▫️
s100.pipeline.vector.stage.feature_xml 48.01 46.34 -3.5% ▫️
s100.pipeline.vector.stage.lua 4305.17 4452.94 +3.4% ▫️
s100.pipeline.vector.stage.rule_select 4.87 5.64 +15.8%
s100.pipeline.vector.stage.sort 2.07 2.27 +9.5%
s100.pipeline.vector.stage.viewing_groups 3.81 3.98 +4.6% ▫️
s100.pipeline.vector.stage.xslt 0.27 0.28 +3.0% ▫️
s100.render.frame 5092.93 5137.48 +0.9% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 7.00 7.00 +0.0% ▫️
s100.featurecatalogue.cache.hit.count 6.00 6.00 +0.0% ▫️
s100.featurecatalogue.cache.miss.count 1.00 1.00 +0.0% ▫️
s100.lua.execute.duration 1185.80 1263.57 +6.6%
s100.lua.features.count 700.00 700.00 +0.0% ▫️
s100.lua.instructions.emitted.count 735.00 735.00 +0.0% ▫️
s100.lua.rule.invoke.count 7.00 7.00 +0.0% ▫️
s100.lua.rule.invoke.count 77.00 77.00 +0.0% ▫️
s100.lua.rule.invoke.duration 918.72 974.14 +6.0%
s100.lua.rule.invoke.duration 6.53 6.46 -1.0% ▫️
s100.lua.source.cache.hit.count 292.00 292.00 +0.0% ▫️
s100.lua.source.cache.miss.count 23.00 23.00 +0.0% ▫️
s100.pattern.cache.hit.count 63.00 63.00 +0.0% ▫️
s100.pattern.cache.miss.count 28.00 28.00 +0.0% ▫️
s100.pipeline.drawinginstructions.out 735.00 735.00 +0.0% ▫️
s100.pipeline.duration 1215.72 1293.86 +6.4%
s100.pipeline.features.in 84.00 84.00 +0.0% ▫️
s100.pipeline.stage.duration 0.30 0.26 -12.2%
s100.pipeline.stage.duration 18.89 18.80 -0.5% ▫️
s100.pipeline.stage.duration 1186.94 1264.74 +6.6%
s100.pipeline.stage.duration 4.06 4.19 +3.1% ▫️
s100.pipeline.stage.duration 2.23 2.48 +11.2%
s100.pipeline.stage.duration 0.84 0.86 +1.5% ▫️
s100.pipeline.stage.duration 0.87 0.85 -2.8% ▫️
s100.pipeline.stage.instructions.count 0.00 0.00 N/A ▫️
s100.pipeline.stage.instructions.count 735.00 735.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 735.00 735.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 735.00 735.00 +0.0% ▫️
s100.portrayal.cache.hit.count 24.00 24.00 +0.0% ▫️
s100.portrayal.cache.hit.count 292.00 292.00 +0.0% ▫️
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.portrayal.cache.hit.count 36.00 36.00 +0.0% ▫️
s100.portrayal.cache.miss.count 4.00 4.00 +0.0% ▫️
s100.portrayal.cache.miss.count 23.00 23.00 +0.0% ▫️
s100.portrayal.cache.miss.count 6.00 6.00 +0.0% ▫️
s100.render.frame.duration 1348.22 1331.89 -1.2% ▫️
s100.render.instructions.processed.count 735.00 735.00 +0.0% ▫️
s100.render.styles.applied.count 693.00 693.00 +0.0% ▫️
s100.symbol.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.symbol.cache.miss.count 14.00 14.00 +0.0% ▫️
s100.symbol.resolve.duration 0.03 0.03 -1.5% ▫️
s100.symbol.resolve.duration 5.17 8.09 +56.6%

s101-portray-warm

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 160.41 120.41
Baseline MAD (ms) 26.61
Δ median -24.9%
z (Δ/MAD) -1.50

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.lua.execute 4369.02 4137.58 -5.3% ▫️
s100.lua.rule.invoke 3620.39 3435.63 -5.1% ▫️
s100.pipeline.vector.process 4449.13 4217.73 -5.2% ▫️
s100.pipeline.vector.stage.assemble 0.21 0.21 -3.8% ▫️
s100.pipeline.vector.stage.feature_xml 66.32 66.78 +0.7% ▫️
s100.pipeline.vector.stage.lua 4370.39 4138.85 -5.3% ▫️
s100.pipeline.vector.stage.rule_select 3.93 3.78 -3.9% ▫️
s100.pipeline.vector.stage.sort 2.74 2.94 +7.1%
s100.pipeline.vector.stage.viewing_groups 4.37 4.41 +0.9% ▫️
s100.pipeline.vector.stage.xslt 0.25 0.24 -2.6% ▫️
s100.render.frame 76.96 87.61 +13.8%

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.featurecatalogue.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.lua.execute.duration 1077.86 752.23 -30.2%
s100.lua.features.count 700.00 700.00 +0.0% ▫️
s100.lua.instructions.emitted.count 735.00 735.00 +0.0% ▫️
s100.lua.rule.invoke.count 7.00 7.00 +0.0% ▫️
s100.lua.rule.invoke.count 77.00 77.00 +0.0% ▫️
s100.lua.rule.invoke.duration 918.69 630.03 -31.4%
s100.lua.rule.invoke.duration 6.29 15.22 +142.0%
s100.lua.source.cache.hit.count 315.00 315.00 +0.0% ▫️
s100.pattern.cache.hit.count 87.00 87.00 +0.0% ▫️
s100.pattern.cache.miss.count 4.00 4.00 +0.0% ▫️
s100.pipeline.drawinginstructions.out 735.00 735.00 +0.0% ▫️
s100.pipeline.duration 1092.45 766.57 -29.8%
s100.pipeline.features.in 84.00 84.00 +0.0% ▫️
s100.pipeline.stage.duration 0.03 0.02 -36.9%
s100.pipeline.stage.duration 11.52 11.45 -0.7% ▫️
s100.pipeline.stage.duration 1078.16 752.48 -30.2%
s100.pipeline.stage.duration 0.90 0.84 -7.4% ▫️
s100.pipeline.stage.duration 0.50 0.51 +2.6% ▫️
s100.pipeline.stage.duration 0.13 0.15 +16.1%
s100.pipeline.stage.duration 0.03 0.03 +2.7% ▫️
s100.pipeline.stage.instructions.count 0.00 0.00 N/A ▫️
s100.pipeline.stage.instructions.count 735.00 735.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 735.00 735.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 735.00 735.00 +0.0% ▫️
s100.portrayal.cache.hit.count 4.00 4.00 +0.0% ▫️
s100.portrayal.cache.hit.count 315.00 315.00 +0.0% ▫️
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.portrayal.cache.hit.count 6.00 6.00 +0.0% ▫️
s100.render.frame.duration 174.04 179.07 +2.9% ▫️
s100.render.instructions.processed.count 735.00 735.00 +0.0% ▫️
s100.render.styles.applied.count 693.00 693.00 +0.0% ▫️
s100.symbol.cache.hit.count 19.00 19.00 +0.0% ▫️
s100.symbol.cache.miss.count 2.00 2.00 +0.0% ▫️
s100.symbol.resolve.duration 0.06 0.05 -12.0%
s100.symbol.resolve.duration 0.23 0.26 +12.3%

s101-render-warm

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 169.63 96.19
Baseline MAD (ms) 11.18
Δ median -43.3%
z (Δ/MAD) -6.57

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.lua.execute 4356.01 3825.80 -12.2%
s100.lua.rule.invoke 3516.92 3141.06 -10.7%
s100.pipeline.vector.process 4434.24 3906.06 -11.9%
s100.pipeline.vector.stage.assemble 0.19 0.18 -7.7% ▫️
s100.pipeline.vector.stage.feature_xml 63.37 67.89 +7.1%
s100.pipeline.vector.stage.lua 4357.21 3826.91 -12.2%
s100.pipeline.vector.stage.rule_select 3.65 3.30 -9.7% ▫️
s100.pipeline.vector.stage.sort 4.49 3.23 -28.0%
s100.pipeline.vector.stage.viewing_groups 6.43 4.65 -27.8%
s100.pipeline.vector.stage.xslt 0.22 0.22 -3.2% ▫️
s100.render.frame 77.33 77.55 +0.3% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.featurecatalogue.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.lua.execute.duration 1212.39 546.44 -54.9%
s100.lua.features.count 700.00 700.00 +0.0% ▫️
s100.lua.instructions.emitted.count 735.00 735.00 +0.0% ▫️
s100.lua.rule.invoke.count 7.00 7.00 +0.0% ▫️
s100.lua.rule.invoke.count 77.00 77.00 +0.0% ▫️
s100.lua.rule.invoke.duration 1011.62 444.17 -56.1%
s100.lua.rule.invoke.duration 6.11 2.81 -54.1%
s100.lua.source.cache.hit.count 315.00 315.00 +0.0% ▫️
s100.pattern.cache.hit.count 87.00 87.00 +0.0% ▫️
s100.pattern.cache.miss.count 4.00 4.00 +0.0% ▫️
s100.pipeline.drawinginstructions.out 735.00 735.00 +0.0% ▫️
s100.pipeline.duration 1229.45 562.76 -54.2%
s100.pipeline.features.in 84.00 84.00 +0.0% ▫️
s100.pipeline.stage.duration 0.02 0.02 +1.5% ▫️
s100.pipeline.stage.duration 13.27 13.41 +1.0% ▫️
s100.pipeline.stage.duration 1212.63 546.69 -54.9%
s100.pipeline.stage.duration 0.83 0.80 -3.4% ▫️
s100.pipeline.stage.duration 1.39 0.46 -67.1%
s100.pipeline.stage.duration 0.15 0.14 -3.6% ▫️
s100.pipeline.stage.duration 0.03 0.03 +22.6%
s100.pipeline.stage.instructions.count 0.00 0.00 N/A ▫️
s100.pipeline.stage.instructions.count 735.00 735.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 735.00 735.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 735.00 735.00 +0.0% ▫️
s100.portrayal.cache.hit.count 4.00 4.00 +0.0% ▫️
s100.portrayal.cache.hit.count 315.00 315.00 +0.0% ▫️
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.portrayal.cache.hit.count 6.00 6.00 +0.0% ▫️
s100.render.frame.duration 185.37 175.26 -5.5% ▫️
s100.render.instructions.processed.count 735.00 735.00 +0.0% ▫️
s100.render.styles.applied.count 693.00 693.00 +0.0% ▫️
s100.symbol.cache.hit.count 19.00 19.00 +0.0% ▫️
s100.symbol.cache.miss.count 2.00 2.00 +0.0% ▫️
s100.symbol.resolve.duration 0.05 0.04 -9.2% ▫️
s100.symbol.resolve.duration 0.22 0.25 +14.2%

s102-coverage

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 1.55 1.52
Baseline MAD (ms) 0.02
Δ median -1.9%
z (Δ/MAD) -1.35

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.pipeline.coverage.process 57.45 54.24 -5.6% ▫️
s100.pipeline.coverage.stage.read 4.96 4.80 -3.2% ▫️
s100.pipeline.coverage.stage.resolve 49.12 45.98 -6.4% ▫️
s100.render.coverage.build 78.85 78.92 +0.1% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.coverage.cells 4557.00 4557.00 +0.0% ▫️
s100.hdf5.read.bytes 5208.00 5208.00 +0.0% ▫️
s100.hdf5.read.duration 20.95 21.00 +0.2% ▫️
s100.hdf5.read.duration 29.20 29.18 -0.1% ▫️
s100.hdf5.read.duration 7.49 7.51 +0.2% ▫️
s100.pipeline.duration 11.46 10.00 -12.7%
s100.pipeline.stage.duration 0.93 0.97 +4.0% ▫️
s100.pipeline.stage.duration 10.02 8.31 -17.0%
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️

s102-coverage-open

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 2.87 2.73
Baseline MAD (ms) 0.04
Δ median -4.7%
z (Δ/MAD) -3.44

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.dataset.open 80.07 84.04 +5.0% ▫️
s100.hdf5.dataset.read 11.84 13.81 +16.7%
s100.hdf5.file.open 18.19 18.68 +2.7% ▫️
s100.hdf5.open 19.06 19.33 +1.4% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.hdf5.read.bytes 36456.00 36456.00 +0.0% ▫️
s100.hdf5.read.duration 6.61 5.96 -9.9% ▫️
s100.hdf5.read.duration 2.34 1.99 -14.7%
s100.hdf5.read.duration 4.37 4.23 -3.2% ▫️

s102-coverage-render-large

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 140.87 139.39
Baseline MAD (ms) 1.83
Δ median -1.0%
z (Δ/MAD) -0.81

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.pipeline.coverage.process 194.75 171.02 -12.2%
s100.pipeline.coverage.stage.read 114.63 107.52 -6.2% ▫️
s100.pipeline.coverage.stage.resolve 77.17 60.39 -21.7%
s100.render.coverage.build 5035.33 4850.15 -3.7% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.coverage.cells 7000000.00 7000000.00 +0.0% ▫️
s100.hdf5.read.bytes 8000000.00 8000000.00 +0.0% ▫️
s100.hdf5.read.duration 0.09 0.09 +6.9%
s100.hdf5.read.duration 2.21 2.43 +9.8%
s100.hdf5.read.duration 1.13 2.31 +104.1%
s100.pipeline.duration 41.21 36.10 -12.4%
s100.pipeline.stage.duration 23.39 23.73 +1.5% ▫️
s100.pipeline.stage.duration 17.22 11.77 -31.6%
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️

s124-vector

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 0.47 0.49
Baseline MAD (ms) 0.01
Δ median +5.9%
z (Δ/MAD) +2.04

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.pipeline.vector.process 9.33 10.00 +7.1%
s100.pipeline.vector.stage.assemble 0.33 0.36 +11.7%
s100.pipeline.vector.stage.feature_xml 1.42 1.72 +21.0%
s100.pipeline.vector.stage.rule_select 0.35 0.34 -3.3% ▫️
s100.pipeline.vector.stage.sort 0.26 0.28 +8.7%
s100.pipeline.vector.stage.viewing_groups 0.69 0.64 -7.6% ▫️
s100.pipeline.vector.stage.xslt 4.24 4.57 +7.8%
s100.render.frame 1.12 1.30 +15.6%
s100.xslt.transform 1.71 1.93 +12.4%

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.featurecatalogue.cache.miss.count 1.00 1.00 +0.0% ▫️
s100.pipeline.drawinginstructions.out 14.00 14.00 +0.0% ▫️
s100.pipeline.duration 56.62 54.32 -4.1% ▫️
s100.pipeline.features.in 7.00 7.00 +0.0% ▫️
s100.pipeline.stage.duration 0.99 0.99 +0.3% ▫️
s100.pipeline.stage.duration 3.34 3.29 -1.4% ▫️
s100.pipeline.stage.duration 1.09 1.10 +1.0% ▫️
s100.pipeline.stage.duration 0.07 0.05 -18.5%
s100.pipeline.stage.duration 0.11 0.08 -28.7%
s100.pipeline.stage.duration 50.30 48.15 -4.3% ▫️
s100.pipeline.stage.instructions.count 14.00 14.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 14.00 14.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 14.00 14.00 +0.0% ▫️
s100.portrayal.cache.hit.count 13.00 13.00 +0.0% ▫️
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.portrayal.cache.hit.count 6.00 6.00 +0.0% ▫️
s100.portrayal.cache.miss.count 1.00 1.00 +0.0% ▫️
s100.portrayal.cache.miss.count 1.00 1.00 +0.0% ▫️
s100.render.frame.duration 2.21 2.31 +4.7% ▫️
s100.render.instructions.processed.count 14.00 14.00 +0.0% ▫️
s100.render.styles.applied.count 14.00 14.00 +0.0% ▫️
s100.xslt.transform.duration 10.30 10.23 -0.6% ▫️

s201-vector

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 0.37 0.38
Baseline MAD (ms) 0.04
Δ median +2.1%
z (Δ/MAD) +0.20

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.pipeline.vector.process 7.88 7.79 -1.1% ▫️
s100.pipeline.vector.stage.assemble 0.15 0.16 +6.6%
s100.pipeline.vector.stage.feature_xml 0.87 0.97 +12.2%
s100.pipeline.vector.stage.rule_select 0.34 0.33 -2.3% ▫️
s100.pipeline.vector.stage.sort 0.15 0.14 -1.4% ▫️
s100.pipeline.vector.stage.viewing_groups 0.55 0.51 -7.4% ▫️
s100.pipeline.vector.stage.xslt 3.90 3.75 -3.9% ▫️
s100.render.frame 0.40 0.38 -6.9% ▫️
s100.xslt.transform 2.12 2.06 -3.2% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.featurecatalogue.cache.miss.count 1.00 1.00 +0.0% ▫️
s100.pipeline.drawinginstructions.out 0.00 0.00 N/A ▫️
s100.pipeline.duration 145.78 142.64 -2.1% ▫️
s100.pipeline.features.in 7.00 7.00 +0.0% ▫️
s100.pipeline.stage.duration 0.01 0.01 -11.6%
s100.pipeline.stage.duration 8.45 8.06 -4.6% ▫️
s100.pipeline.stage.duration 0.13 0.11 -14.4%
s100.pipeline.stage.duration 0.06 0.05 -10.8%
s100.pipeline.stage.duration 0.05 0.04 -9.2% ▫️
s100.pipeline.stage.duration 136.46 133.84 -1.9% ▫️
s100.pipeline.stage.instructions.count 0.00 0.00 N/A ▫️
s100.pipeline.stage.instructions.count 0.00 0.00 N/A ▫️
s100.pipeline.stage.instructions.count 0.00 0.00 N/A ▫️
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.portrayal.cache.hit.count 6.00 6.00 +0.0% ▫️
s100.portrayal.cache.miss.count 1.00 1.00 +0.0% ▫️
s100.render.frame.duration 0.07 0.08 +14.4%
s100.render.instructions.processed.count 0.00 0.00 N/A ▫️
s100.render.styles.applied.count 0.00 0.00 N/A ▫️
s100.xslt.transform.duration 21.66 20.43 -5.7% ▫️

Generated by EncDotNet.S100.PerfReport gate command

@philliphoff philliphoff merged commit 2dfbb88 into main May 20, 2026
10 checks passed
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