Skip to content

Adopt EncDotNet 0.8.0 in the S-101 reader, update applicator and S-57 translator - #892

Merged
philliphoff merged 3 commits into
mainfrom
claude/adopt-encdotnet-0.8
Oct 12, 2026
Merged

philliphoff merged 3 commits into
mainfrom
claude/adopt-encdotnet-0.8

Conversation

@philliphoff

@philliphoff philliphoff commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

This covers items 1–4 of #890. Item 5, allocation budgets for S100, is left for a follow-up.

1. Move to EncDotNet 0.8.0

  • EncDotNet.Iso8211 and EncDotNet.S57 go from 0.7.2 to 0.8.0.
  • S57FeaturePointer.Name is now an S57LongName, so S57ToS101Translator keys its long-name indexes by S57LongName for both records and pointers. The Lnam(fp.Name) calls now use fp.Name directly.
  • Why not keep the (agency, fid, sub) tuple: the record side converts a signed int FIDN to long, while the pointer side would convert an unsigned uint. For any FIDN above 2³¹ the two keys would differ, so the pointer would stop matching its target.
  • A record without FOID keys as the all-zero long name, as it did before.

2–3. S101DocumentReader: stream records and read by ordinal

  • Records are read one at a time with Iso8211DocumentReader.EnumerateRecords, instead of building the whole ISO 8211 document first.
  • Repeating fields (C2IL, C3IL, PTAS, CUCO, RIAS, ATTR, SPAS, FASC, INAS and the catalogue fields) are read by ordinal, with no group object or name lookup per repetition.
  • Repetitions are counted the way GetSubfieldGroups() counted them. That includes a final repetition cut short by the end of the field, which GroupCount would leave out.
  • Missing subfields behave as before: required ones throw the same KeyNotFoundException, and PAIX, NARC, ATVL and the update instructions default as the old try/catch blocks did.
  • New tests in S101DocumentReaderTruncatedFieldTests pin this. They pass on the previous reader, and fail if the loop uses GroupCount.

4. S101UpdateApplicator: no list search on delete

  • Deleting a feature no longer calls order.Remove. Its RCID stays in the order and is skipped when the result is built.
  • A feature inserted again after a delete is output only at its new, final position, exactly as before.
  • S101UpdateApplicatorFeatureOrderTests compares 2,000 random update sequences against the list-based merge. It passes on the previous code, and fails if the reinsert handling is broken.

Test helpers

  • SyntheticS57Cell edits a field's bytes through a writable view of the reader's private copy of the file. Iso8211Field.Data is now ReadOnlyMemory<byte>.
  • The translator tests build feature pointers as S57LongName.

Perf gate (.github/workflows/perf.yml)

  • To compare against main, the gate builds main's library code with this PR's perf tooling overlaid, including the PR's whole Directory.Packages.props.
  • That also upgraded packages main already uses. With EncDotNet 0.8.0, main's translator no longer compiled, so the gate failed before measuring anything.
  • Even for a compatible upgrade, it would have measured the new package on both sides, hiding the upgrade's effect.
  • The overlay now keeps main's version for every package main declares. Only packages new in the PR take the PR's version, which was the overlay's original purpose.
  • I ran the step locally on main with this branch as head: the base PerfRunner builds against EncDotNet 0.7.2.

Results

Before After
Read US4MD81M as S-101 (3.4 MB) 238 ms / 156 MB 105 ms / 36 MB
Read US5WA22M as S-101 (1.9 MB) 139 ms / 90 MB 45 ms / 24 MB
Read US3WA01M as S-101 (1.6 MB) 118 ms / 74 MB 40 ms / 18 MB
Delete a third of US4MD81M's 7,378 features 13.0 ms 2.1 ms

Measured locally in Release, as medians of 9 runs. The S-101 files are NOAA cells (with their updates applied) translated by S57ToS101Translator and written with S101DocumentWriter.

The output is unchanged. I fingerprinted every property of the resulting S101Document before any change and again after each step, and all fingerprints match. The inputs were:

  • all 19 datasets in tests/datasets/S101, opened from a file and from a stream;
  • 9 NOAA cells with their updates: the translated document, the written bytes, and the document read back.

Spec alignment

  • S-100 framework (s100-framework)
  • S-101 ENC (s101-enc)
  • S-102 bathymetry (s102-bathymetry)
  • S-104 water level (s104-water-level)
  • S-111 surface currents (s111-surface-currents)
  • S-124 navigational warnings (s124-nav-warnings)
  • S-129 under keel clearance (s129-ukc)
  • N/A — change is purely infrastructural (build, CI, docs, tooling)

Spec section references cited in code/docs:

None new. ISO 8211 reads still go through EncDotNet.Iso8211 (s101-enc checklist item 1).

Tests

  • Added/updated xunit tests under tests/: S101DocumentReaderTruncatedFieldTests and S101UpdateApplicatorFeatureOrderTests.
  • Tests requiring real data files skip via Assert.SkipUnless/Assert.SkipWhen. The new tests need no real data.
  • dotnet test --configuration Release passes locally: everything passes except the 5 tests below.
    • 5 tests in EncDotNet.S100.Cli.Tests (CliVersionAndUpdateTests ×4 and SkillOutputTests.RootHelpDocumentsSkillOption) fail in my sandbox. They fail identically on main, so this branch doesn't cause them.
    • S100MapSessionTests.AddDatasetAsyncFailsWhenRemoveCancelsRenderBeforeOwnershipIsReleased failed once during the full run, while another build was competing for the machine. It passes when re-run, both on this branch and on main.
  • New or changed viewer UI has automation ids and accessible names. Not applicable: no UI changes.

Documentation

  • Updated the affected project's src/<project>/README.md. Not needed: no public API or behaviour change.
  • Updated conceptual docs under docs/. Not needed, for the same reason.
  • New public APIs have XML doc comments. There are no new public APIs.

Dependencies

  • No new NuGet dependencies, OR versions added to Directory.Packages.props. Two existing package versions are bumped there, and nothing is added.
  • gh-advisory-database security check run for any new dependency. Not applicable: no new dependencies.

Breaking changes

None in EncDotNet.S100's public API. EncDotNet 0.8.0's own breaking changes, listed in philliphoff/EncDotNet#34 and #35, are absorbed here.

Closes #890 except item 5.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YagvELyJKBANk61DyFGUNJ

… translator

Part of #890.

- Move EncDotNet.Iso8211 and EncDotNet.S57 to 0.8.0. S57FeaturePointer.Name
  is now an S57LongName, so the translator keys its long-name indexes by
  S57LongName on both sides. Keeping the (agency, fid, sub) tuple would have
  converted a record's FIDN from int but a pointer's from uint, so a FIDN
  above 2^31 would no longer have matched. A record without FOID keys as
  the all-zero long name, as before.
- S101DocumentReader reads records one at a time with
  Iso8211DocumentReader.EnumerateRecords instead of building the whole
  ISO 8211 document, and reads repeating fields by ordinal instead of
  creating a group object per repetition. Repetitions are counted as
  GetSubfieldGroups counted them, including a final one cut short by the
  end of the field, and missing subfields default or throw as before; new
  tests pin both and pass on the previous reader too.
- S101UpdateApplicator no longer searches the feature order list on every
  delete. A deleted RCID stays in the order and is skipped; a feature
  inserted again after a delete is output only at its new, final position.
  A randomized test compares the result with the list-based merge.
- Test helpers: SyntheticS57Cell edits field data through a writable view
  of the reader's private copy, and the translator tests build feature
  pointers as S57LongName.

Reading US4MD81M translated to S-101 (3.4 MB) takes 105 ms and allocates
36 MB, down from 238 ms and 156 MB. Deleting a third of its 7,378
features in an update takes 2 ms instead of 13 ms. The 19 S-101 test
datasets, and 9 NOAA cells translated, written and read back, give the
same model fingerprints as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YagvELyJKBANk61DyFGUNJ
The perf gate overlays the PR's Directory.Packages.props onto the base
tree so the overlaid PerfRunner can restore packages the PR adds. That
also upgraded packages the base already uses, so the base library code
was built against dependency versions it wasn't written for: this PR's
move to EncDotNet 0.8.0 made the base build fail, and a compatible
upgrade would have been measured on both sides, hiding its effect.

Keep the base's version for every package the base declares; only
packages new in the PR take the PR's version. Checked by running the
step on main with this branch as head: the base PerfRunner builds
against EncDotNet 0.7.2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YagvELyJKBANk61DyFGUNJ
The base step now writes the base's package versions into
Directory.Packages.props as a local change, and a plain checkout of the
PR head carried that change over, so the candidate was built against
the base's EncDotNet 0.7.2. Check out the PR head with --force so the
candidate builds from the PR tree as committed. Simulated locally: after
the overlay and the forced checkout, the tree is clean and on 0.8.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YagvELyJKBANk61DyFGUNJ
@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 +3.0 +0.46 0.58 20/20
s101-pick-warm ✅ pass +1.8 +0.84 0.23 5/5
s101-portray-cold ✅ pass +2.8 +0.41 384.41 20/20
s101-portray-warm ✅ pass -4.8 -2.49 5.76 20/20
s101-real-cold ✅ pass +4.2 +1.46 0.24 5/5
s101-real-warm ✅ pass -3.6 -0.68 0.27 5/5
s101-render-repeat ✅ pass -2.6 -1.55 66.63 20/20
s101-render-warm ✅ pass -1.7 -0.36 6.37 20/20
s102-coverage ✅ pass +14.0 +6.10 1.32 20/20
s102-coverage-open ✅ pass -3.2 -3.06 3.01 20/20
s102-coverage-render-large ✅ pass +0.5 +0.50 139.09 20/20
s102-coverage-render-repeat ✅ pass -1.1 -0.82 884.07 20/20
s102-coverage-viewport-fit ✅ pass -1.6 -1.00 87.29 20/20
s102-coverage-viewport-zoomed-in ✅ pass -2.1 -0.44 1.77 20/20
s102-coverage-viewport-zoomed-out ✅ pass +4.2 +1.26 6.19 20/20
s102-real-warm ✅ pass -0.7 -0.08 0.09 5/5
s111-arrow-repeat ✅ pass +1.3 +0.05 4.42 20/20
s111-real-warm ✅ pass +37.6 +29.73 0.09 5/5
s124-vector ✅ pass -4.2 -0.70 0.35 20/20
s201-vector ✅ pass +0.4 +0.13 0.49 20/20

exchange-set-open

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 0.58 0.60
Baseline MAD (ms) 0.04 —
Δ median — +3.0%
z (Δ/MAD) — +0.46

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.asset.read 54.48 54.15 -0.6% ▫️
s100.exchangeset.parse 56.83 56.04 -1.4% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.asset.read.duration 0.23 0.26 +10.6% ❌

s101-pick-warm

Iteration statistics

Stat Baseline Candidate
Samples 5 5
Median (ms) 0.23 0.24
Baseline MAD (ms) 0.00 —
Δ median — +1.8%
z (Δ/MAD) — +0.84

s101-portray-cold

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 384.41 395.14
Baseline MAD (ms) 26.05 —
Δ median — +2.8%
z (Δ/MAD) — +0.41

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.featurecatalogue.parse 219.60 220.52 +0.4% ▫️
s100.lua.execute 13244.03 14240.84 +7.5% ❌
s100.lua.rule.invoke 11247.25 12143.75 +8.0% ❌
s100.pipeline.vector.process 13330.05 14327.80 +7.5% ❌
s100.pipeline.vector.stage.lua 13252.55 14249.43 +7.5% ❌
s100.pipeline.vector.stage.rule_select 30.25 30.28 +0.1% ▫️
s100.pipeline.vector.stage.sort 26.00 26.74 +2.9% ▫️
s100.pipeline.vector.stage.viewing_groups 36.61 37.35 +2.0% ▫️
s100.render.frame 4056.20 4116.46 +1.5% ▫️

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 2673.04 2845.85 +6.5% ❌
s100.lua.feature.instructions.count 28.00 28.00 +0.0% ▫️
s100.lua.feature.instructions.count 63.00 63.00 +0.0% ▫️
s100.lua.feature.instructions.count 63.00 63.00 +0.0% ▫️
s100.lua.feature.instructions.count 14.00 14.00 +0.0% ▫️
s100.lua.feature.instructions.count 42.00 42.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 217.00 217.00 +0.0% ▫️
s100.lua.feature.instructions.count 840.00 840.00 +0.0% ▫️
s100.lua.feature.instructions.count 49.00 49.00 +0.0% ▫️
s100.lua.feature.instructions.count 14.00 14.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 49.00 49.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 21.00 21.00 +0.0% ▫️
s100.lua.feature.instructions.count 14.00 14.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 49.00 49.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 14.00 14.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 840.00 840.00 +0.0% ▫️
s100.lua.feature.instructions.count 28.00 28.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 28.00 28.00 +0.0% ▫️
s100.lua.feature.instructions.count 14.00 14.00 +0.0% ▫️
s100.lua.features.count 2478.00 2478.00 +0.0% ▫️
s100.lua.instructions.emitted.count 4004.00 4004.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 2271.31 2412.52 +6.2% ❌
s100.lua.rule.invoke.duration 6.40 6.65 +4.0% ▫️
s100.lua.source.cache.hit.count 1290.00 1290.00 +0.0% ▫️
s100.lua.source.cache.miss.count 215.00 215.00 +0.0% ▫️
s100.pattern.cache.hit.count 210.00 210.00 +0.0% ▫️
s100.pattern.cache.miss.count 14.00 14.00 +0.0% ▫️
s100.pipeline.drawinginstructions.out 4004.00 4004.00 +0.0% ▫️
s100.pipeline.duration 2691.45 2862.67 +6.4% ❌
s100.pipeline.features.in 217.00 217.00 +0.0% ▫️
s100.pipeline.stage.duration 2674.70 2847.49 +6.5% ❌
s100.pipeline.stage.duration 5.72 5.57 -2.7% ▫️
s100.pipeline.stage.duration 6.13 5.12 -16.5% ✅
s100.pipeline.stage.duration 2.26 1.81 -20.0% ✅
s100.pipeline.stage.instructions.count 4004.00 4004.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 4004.00 4004.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 4004.00 4004.00 +0.0% ▫️
s100.portrayal.cache.hit.count 12.00 12.00 +0.0% ▫️
s100.portrayal.cache.hit.count 12.00 12.00 +0.0% ▫️
s100.portrayal.cache.hit.count 1290.00 1290.00 +0.0% ▫️
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.portrayal.cache.hit.count 96.00 96.00 +0.0% ▫️
s100.portrayal.cache.miss.count 2.00 2.00 +0.0% ▫️
s100.portrayal.cache.miss.count 2.00 2.00 +0.0% ▫️
s100.portrayal.cache.miss.count 215.00 215.00 +0.0% ▫️
s100.portrayal.cache.miss.count 16.00 16.00 +0.0% ▫️
s100.render.frame.duration 788.46 783.82 -0.6% ▫️
s100.render.instructions.processed.count 4004.00 4004.00 +0.0% ▫️
s100.render.styles.applied.count 4200.00 4200.00 +0.0% ▫️
s100.symbol.cache.hit.count 364.00 364.00 +0.0% ▫️
s100.symbol.cache.miss.count 98.00 98.00 +0.0% ▫️
s100.symbol.resolve.duration 0.36 0.36 -1.5% ▫️
s100.symbol.resolve.duration 16.37 22.62 +38.1% ❌

s101-portray-warm

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 5.76 5.49
Baseline MAD (ms) 0.11 —
Δ median — -4.8%
z (Δ/MAD) — -2.49

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.lua.execute 1213.72 1206.28 -0.6% ▫️
s100.lua.rule.invoke 1085.29 1083.70 -0.1% ▫️
s100.pipeline.vector.process 1219.63 1212.69 -0.6% ▫️
s100.pipeline.vector.stage.lua 1213.99 1206.58 -0.6% ▫️
s100.pipeline.vector.stage.rule_select 1.28 1.36 +6.2% ❌
s100.pipeline.vector.stage.sort 3.14 3.33 +6.1% ❌
s100.pipeline.vector.stage.viewing_groups 3.85 4.18 +8.6% ❌
s100.render.frame 545.45 636.83 +16.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 244.82 223.64 -8.6% ▫️
s100.lua.feature.instructions.count 4.00 4.00 +0.0% ▫️
s100.lua.feature.instructions.count 9.00 9.00 +0.0% ▫️
s100.lua.feature.instructions.count 9.00 9.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 6.00 6.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 31.00 31.00 +0.0% ▫️
s100.lua.feature.instructions.count 120.00 120.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 3.00 3.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 120.00 120.00 +0.0% ▫️
s100.lua.feature.instructions.count 4.00 4.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 4.00 4.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.features.count 354.00 354.00 +0.0% ▫️
s100.lua.instructions.emitted.count 572.00 572.00 +0.0% ▫️
s100.lua.rule.invoke.count 1.00 1.00 +0.0% ▫️
s100.lua.rule.invoke.count 11.00 11.00 +0.0% ▫️
s100.lua.rule.invoke.duration 221.68 200.11 -9.7% ▫️
s100.lua.rule.invoke.duration 0.46 0.40 -11.3% ✅
s100.lua.source.cache.hit.count 215.00 215.00 +0.0% ▫️
s100.pattern.cache.hit.count 222.00 222.00 +0.0% ▫️
s100.pattern.cache.miss.count 2.00 2.00 +0.0% ▫️
s100.pipeline.drawinginstructions.out 572.00 572.00 +0.0% ▫️
s100.pipeline.duration 245.96 224.78 -8.6% ▫️
s100.pipeline.features.in 31.00 31.00 +0.0% ▫️
s100.pipeline.stage.duration 244.87 223.69 -8.6% ▫️
s100.pipeline.stage.duration 0.26 0.25 -5.1% ▫️
s100.pipeline.stage.duration 0.57 0.56 -2.5% ▫️
s100.pipeline.stage.duration 0.11 0.11 +0.2% ▫️
s100.pipeline.stage.instructions.count 572.00 572.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 572.00 572.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 572.00 572.00 +0.0% ▫️
s100.portrayal.cache.hit.count 14.00 14.00 +0.0% ▫️
s100.portrayal.cache.hit.count 14.00 14.00 +0.0% ▫️
s100.portrayal.cache.hit.count 215.00 215.00 +0.0% ▫️
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.portrayal.cache.hit.count 112.00 112.00 +0.0% ▫️
s100.render.frame.duration 99.31 102.44 +3.2% ▫️
s100.render.instructions.processed.count 4004.00 4004.00 +0.0% ▫️
s100.render.styles.applied.count 4200.00 4200.00 +0.0% ▫️
s100.symbol.cache.hit.count 448.00 448.00 +0.0% ▫️
s100.symbol.cache.miss.count 14.00 14.00 +0.0% ▫️
s100.symbol.resolve.duration 0.41 0.39 -4.4% ▫️
s100.symbol.resolve.duration 2.00 8.20 +309.0% ❌

s101-real-cold

Iteration statistics

Stat Baseline Candidate
Samples 5 5
Median (ms) 0.24 0.25
Baseline MAD (ms) 0.01 —
Δ median — +4.2%
z (Δ/MAD) — +1.46

s101-real-warm

Iteration statistics

Stat Baseline Candidate
Samples 5 5
Median (ms) 0.27 0.26
Baseline MAD (ms) 0.01 —
Δ median — -3.6%
z (Δ/MAD) — -0.68

s101-render-repeat

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 66.63 64.87
Baseline MAD (ms) 1.13 —
Δ median — -2.6%
z (Δ/MAD) — -1.55

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.lua.execute 1163.22 1212.52 +4.2% ▫️
s100.lua.rule.invoke 1053.12 1136.41 +7.9% ❌
s100.pipeline.vector.process 1169.44 1218.91 +4.2% ▫️
s100.pipeline.vector.stage.lua 1163.48 1212.80 +4.2% ▫️
s100.pipeline.vector.stage.rule_select 1.30 1.21 -7.4% ▫️
s100.pipeline.vector.stage.sort 3.35 3.54 +5.7% ❌
s100.pipeline.vector.stage.viewing_groups 4.11 4.41 +7.4% ❌
s100.render.frame 2278.71 2312.87 +1.5% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.featurecatalogue.cache.hit.count 70.00 70.00 +0.0% ▫️
s100.lua.execute.duration 223.88 225.47 +0.7% ▫️
s100.lua.feature.instructions.count 4.00 4.00 +0.0% ▫️
s100.lua.feature.instructions.count 9.00 9.00 +0.0% ▫️
s100.lua.feature.instructions.count 9.00 9.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 6.00 6.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 31.00 31.00 +0.0% ▫️
s100.lua.feature.instructions.count 120.00 120.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 3.00 3.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 120.00 120.00 +0.0% ▫️
s100.lua.feature.instructions.count 4.00 4.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 4.00 4.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.features.count 354.00 354.00 +0.0% ▫️
s100.lua.instructions.emitted.count 572.00 572.00 +0.0% ▫️
s100.lua.rule.invoke.count 1.00 1.00 +0.0% ▫️
s100.lua.rule.invoke.count 11.00 11.00 +0.0% ▫️
s100.lua.rule.invoke.duration 200.42 209.92 +4.7% ▫️
s100.lua.rule.invoke.duration 0.52 0.37 -28.3% ✅
s100.lua.source.cache.hit.count 215.00 215.00 +0.0% ▫️
s100.pattern.cache.hit.count 2238.00 2238.00 +0.0% ▫️
s100.pattern.cache.miss.count 2.00 2.00 +0.0% ▫️
s100.pipeline.drawinginstructions.out 572.00 572.00 +0.0% ▫️
s100.pipeline.duration 225.18 226.77 +0.7% ▫️
s100.pipeline.features.in 31.00 31.00 +0.0% ▫️
s100.pipeline.stage.duration 223.94 225.52 +0.7% ▫️
s100.pipeline.stage.duration 0.27 0.23 -13.5% ✅
s100.pipeline.stage.duration 0.68 0.71 +4.6% ▫️
s100.pipeline.stage.duration 0.11 0.15 +34.7% ❌
s100.pipeline.stage.instructions.count 572.00 572.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 572.00 572.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 572.00 572.00 +0.0% ▫️
s100.portrayal.cache.hit.count 140.00 140.00 +0.0% ▫️
s100.portrayal.cache.hit.count 140.00 140.00 +0.0% ▫️
s100.portrayal.cache.hit.count 215.00 215.00 +0.0% ▫️
s100.portrayal.cache.hit.count 70.00 70.00 +0.0% ▫️
s100.portrayal.cache.hit.count 1120.00 1120.00 +0.0% ▫️
s100.render.frame.duration 337.58 358.92 +6.3% ❌
s100.render.instructions.processed.count 40040.00 40040.00 +0.0% ▫️
s100.render.styles.applied.count 42000.00 42000.00 +0.0% ▫️
s100.symbol.cache.hit.count 4606.00 4606.00 +0.0% ▫️
s100.symbol.cache.miss.count 14.00 14.00 +0.0% ▫️
s100.symbol.resolve.duration 5.08 5.05 -0.7% ▫️
s100.symbol.resolve.duration 2.13 2.12 -0.5% ▫️

s101-render-warm

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 6.37 6.26
Baseline MAD (ms) 0.31 —
Δ median — -1.7%
z (Δ/MAD) — -0.36

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.lua.execute 1125.31 1109.35 -1.4% ▫️
s100.lua.rule.invoke 1047.45 1030.15 -1.7% ▫️
s100.pipeline.vector.process 1131.37 1115.01 -1.4% ▫️
s100.pipeline.vector.stage.lua 1125.56 1109.61 -1.4% ▫️
s100.pipeline.vector.stage.rule_select 1.07 1.09 +2.1% ▫️
s100.pipeline.vector.stage.sort 3.48 3.12 -10.3% ✅
s100.pipeline.vector.stage.viewing_groups 4.21 3.84 -8.8% ▫️
s100.render.frame 554.19 620.55 +12.0% ❌

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 235.30 216.44 -8.0% ▫️
s100.lua.feature.instructions.count 4.00 4.00 +0.0% ▫️
s100.lua.feature.instructions.count 9.00 9.00 +0.0% ▫️
s100.lua.feature.instructions.count 9.00 9.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 6.00 6.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 31.00 31.00 +0.0% ▫️
s100.lua.feature.instructions.count 120.00 120.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 3.00 3.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 7.00 7.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 120.00 120.00 +0.0% ▫️
s100.lua.feature.instructions.count 4.00 4.00 +0.0% ▫️
s100.lua.feature.instructions.count 1.00 1.00 +0.0% ▫️
s100.lua.feature.instructions.count 4.00 4.00 +0.0% ▫️
s100.lua.feature.instructions.count 2.00 2.00 +0.0% ▫️
s100.lua.features.count 354.00 354.00 +0.0% ▫️
s100.lua.instructions.emitted.count 572.00 572.00 +0.0% ▫️
s100.lua.rule.invoke.count 1.00 1.00 +0.0% ▫️
s100.lua.rule.invoke.count 11.00 11.00 +0.0% ▫️
s100.lua.rule.invoke.duration 222.03 200.34 -9.8% ▫️
s100.lua.rule.invoke.duration 0.42 0.37 -13.3% ✅
s100.lua.source.cache.hit.count 215.00 215.00 +0.0% ▫️
s100.pattern.cache.hit.count 222.00 222.00 +0.0% ▫️
s100.pattern.cache.miss.count 2.00 2.00 +0.0% ▫️
s100.pipeline.drawinginstructions.out 572.00 572.00 +0.0% ▫️
s100.pipeline.duration 236.43 217.65 -7.9% ▫️
s100.pipeline.features.in 31.00 31.00 +0.0% ▫️
s100.pipeline.stage.duration 235.33 216.49 -8.0% ▫️
s100.pipeline.stage.duration 0.21 0.21 -0.1% ▫️
s100.pipeline.stage.duration 0.68 0.71 +3.4% ▫️
s100.pipeline.stage.duration 0.09 0.10 +7.8% ❌
s100.pipeline.stage.instructions.count 572.00 572.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 572.00 572.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 572.00 572.00 +0.0% ▫️
s100.portrayal.cache.hit.count 14.00 14.00 +0.0% ▫️
s100.portrayal.cache.hit.count 14.00 14.00 +0.0% ▫️
s100.portrayal.cache.hit.count 215.00 215.00 +0.0% ▫️
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️
s100.portrayal.cache.hit.count 112.00 112.00 +0.0% ▫️
s100.render.frame.duration 98.70 115.59 +17.1% ❌
s100.render.instructions.processed.count 4004.00 4004.00 +0.0% ▫️
s100.render.styles.applied.count 4200.00 4200.00 +0.0% ▫️
s100.symbol.cache.hit.count 448.00 448.00 +0.0% ▫️
s100.symbol.cache.miss.count 14.00 14.00 +0.0% ▫️
s100.symbol.resolve.duration 0.52 0.51 -1.4% ▫️
s100.symbol.resolve.duration 2.07 17.24 +733.1% ❌

s102-coverage

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 1.32 1.50
Baseline MAD (ms) 0.03 —
Δ median — +14.0%
z (Δ/MAD) — +6.10

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.coverage.pyramid.build 5.89 5.86 -0.6% ▫️
s100.dataset.open 310.47 308.22 -0.7% ▫️
s100.hdf5.dataset.read 147.37 147.90 +0.4% ▫️
s100.hdf5.file.open 79.27 82.26 +3.8% ▫️
s100.hdf5.open 38.49 38.16 -0.9% ▫️
s100.pipeline.coverage.process 49.11 65.17 +32.7% ❌
s100.pipeline.coverage.stage.read 8.41 10.97 +30.4% ❌
s100.pipeline.coverage.stage.resolve 36.07 49.58 +37.5% ❌
s100.render.coverage.build 34.29 34.77 +1.4% ▫️

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.coverage.overview.level_selected 0.00 0.00 N/A ▫️
s100.coverage.pyramid.build.duration 0.97 0.91 -6.4% ▫️
s100.hdf5.read.bytes 5208.00 5208.00 +0.0% ▫️
s100.hdf5.read.duration 23.26 23.37 +0.5% ▫️
s100.hdf5.read.duration 29.02 29.26 +0.8% ▫️
s100.hdf5.read.duration 7.49 7.55 +0.7% ▫️
s100.pipeline.duration 9.56 12.02 +25.8% ❌
s100.pipeline.stage.duration 1.30 1.22 -6.5% ▫️
s100.pipeline.stage.duration 6.85 9.39 +37.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) 3.01 2.92
Baseline MAD (ms) 0.03 —
Δ median — -3.2%
z (Δ/MAD) — -3.06

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.dataset.open 86.05 83.26 -3.2% ▫️
s100.hdf5.dataset.read 12.88 11.77 -8.6% ▫️
s100.hdf5.file.open 21.89 22.98 +5.0% ▫️
s100.hdf5.open 23.60 23.41 -0.8% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.hdf5.read.bytes 36456.00 36456.00 +0.0% ▫️
s100.hdf5.read.duration 6.83 7.45 +9.1% ❌
s100.hdf5.read.duration 2.14 2.48 +15.8% ❌
s100.hdf5.read.duration 4.56 4.73 +3.7% ▫️

s102-coverage-render-large

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 139.09 139.85
Baseline MAD (ms) 1.52 —
Δ median — +0.5%
z (Δ/MAD) — +0.50

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.coverage.pyramid.build 333.64 246.04 -26.3% ✅
s100.dataset.open 54.04 39.48 -27.0% ✅
s100.hdf5.dataset.read 16.00 14.51 -9.3% ▫️
s100.hdf5.file.open 9.28 8.41 -9.4% ▫️
s100.hdf5.open 6.43 6.34 -1.4% ▫️
s100.pipeline.coverage.process 304.46 314.39 +3.3% ▫️
s100.pipeline.coverage.stage.read 240.11 251.86 +4.9% ▫️
s100.pipeline.coverage.stage.resolve 61.38 59.45 -3.1% ▫️
s100.render.coverage.build 4775.13 4978.09 +4.3% ▫️

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.coverage.overview.level_selected 0.00 0.00 N/A ▫️
s100.coverage.pyramid.build.duration 44.44 45.61 +2.6% ▫️
s100.hdf5.read.bytes 8000000.00 8000000.00 +0.0% ▫️
s100.hdf5.read.duration 0.09 0.09 -1.3% ▫️
s100.hdf5.read.duration 2.67 2.72 +1.9% ▫️
s100.hdf5.read.duration 1.30 1.33 +2.0% ▫️
s100.pipeline.duration 57.98 65.36 +12.7% ❌
s100.pipeline.stage.duration 48.06 49.92 +3.9% ▫️
s100.pipeline.stage.duration 9.27 14.68 +58.3% ❌
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️

s102-coverage-render-repeat

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 884.07 874.21
Baseline MAD (ms) 12.03 —
Δ median — -1.1%
z (Δ/MAD) — -0.82

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.coverage.pyramid.build 309.61 221.34 -28.5% ✅
s100.dataset.open 22.61 25.19 +11.4% ❌
s100.hdf5.dataset.read 6.37 7.00 +10.0% ❌
s100.hdf5.file.open 1.13 1.28 +14.0% ❌
s100.hdf5.open 3.81 4.13 +8.5% ❌
s100.pipeline.coverage.process 2261.64 2268.60 +0.3% ▫️
s100.pipeline.coverage.stage.read 1891.34 1869.20 -1.2% ▫️
s100.pipeline.coverage.stage.resolve 348.57 377.61 +8.3% ❌
s100.render.coverage.build 33001.62 33348.82 +1.1% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.coverage.cells 70000000.00 70000000.00 +0.0% ▫️
s100.coverage.overview.level_selected 0.00 0.00 N/A ▫️
s100.coverage.pyramid.build.duration 39.78 40.51 +1.8% ▫️
s100.hdf5.read.bytes 8000000.00 8000000.00 +0.0% ▫️
s100.hdf5.read.duration 0.12 0.10 -22.1% ✅
s100.hdf5.read.duration 1.05 1.15 +8.9% ❌
s100.hdf5.read.duration 0.76 0.74 -3.0% ▫️
s100.pipeline.duration 445.42 438.33 -1.6% ▫️
s100.pipeline.stage.duration 372.09 359.24 -3.5% ▫️
s100.pipeline.stage.duration 68.46 74.46 +8.8% ❌
s100.portrayal.cache.hit.count 70.00 70.00 +0.0% ▫️

s102-coverage-viewport-fit

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 87.29 85.91
Baseline MAD (ms) 1.39 —
Δ median — -1.6%
z (Δ/MAD) — -1.00

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.coverage.pyramid.build 202.74 202.26 -0.2% ▫️
s100.dataset.open 22.56 26.72 +18.4% ❌
s100.hdf5.dataset.read 6.45 6.66 +3.1% ▫️
s100.hdf5.file.open 1.14 1.20 +5.7% ❌
s100.hdf5.open 3.58 3.75 +4.7% ▫️
s100.pipeline.coverage.process 223.19 217.33 -2.6% ▫️
s100.pipeline.coverage.stage.read 189.16 183.53 -3.0% ▫️
s100.pipeline.coverage.stage.resolve 32.10 31.77 -1.0% ▫️
s100.render.coverage.build 2858.46 2827.46 -1.1% ▫️

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.coverage.overview.level_selected 0.00 0.00 N/A ▫️
s100.coverage.pyramid.build.duration 39.49 39.77 +0.7% ▫️
s100.hdf5.read.bytes 8000000.00 8000000.00 +0.0% ▫️
s100.hdf5.read.duration 0.10 0.12 +21.1% ❌
s100.hdf5.read.duration 1.03 1.67 +62.5% ❌
s100.hdf5.read.duration 0.73 0.72 -2.0% ▫️
s100.pipeline.duration 40.75 47.56 +16.7% ❌
s100.pipeline.stage.duration 35.25 40.55 +15.0% ❌
s100.pipeline.stage.duration 5.14 6.50 +26.5% ❌
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️

s102-coverage-viewport-zoomed-in

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 1.77 1.74
Baseline MAD (ms) 0.08 —
Δ median — -2.1%
z (Δ/MAD) — -0.44

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.coverage.pyramid.build 35.51 35.02 -1.4% ▫️
s100.dataset.open 23.39 27.83 +19.0% ❌
s100.hdf5.dataset.read 8.06 9.14 +13.4% ❌
s100.hdf5.file.open 1.02 1.24 +21.7% ❌
s100.hdf5.open 3.36 4.81 +43.2% ❌
s100.pipeline.coverage.process 28.59 26.75 -6.4% ▫️
s100.pipeline.coverage.stage.read 2.69 2.77 +3.0% ▫️
s100.pipeline.coverage.stage.resolve 24.73 22.77 -7.9% ▫️
s100.render.coverage.build 33.57 32.76 -2.4% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.coverage.cells 70000.00 70000.00 +0.0% ▫️
s100.coverage.overview.level_selected 0.00 0.00 N/A ▫️
s100.coverage.pyramid.build.duration 6.01 6.36 +5.9% ❌
s100.hdf5.read.bytes 8000000.00 8000000.00 +0.0% ▫️
s100.hdf5.read.duration 0.08 0.10 +28.8% ❌
s100.hdf5.read.duration 1.61 1.72 +6.5% ❌
s100.hdf5.read.duration 0.62 0.84 +35.5% ❌
s100.pipeline.duration 5.13 5.54 +8.2% ❌
s100.pipeline.stage.duration 0.53 0.60 +13.6% ❌
s100.pipeline.stage.duration 4.36 4.64 +6.5% ❌
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️

s102-coverage-viewport-zoomed-out

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 6.19 6.45
Baseline MAD (ms) 0.20 —
Δ median — +4.2%
z (Δ/MAD) — +1.26

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.coverage.pyramid.build 32.49 31.72 -2.4% ▫️
s100.dataset.open 22.86 29.16 +27.5% ❌
s100.hdf5.dataset.read 6.38 7.55 +18.3% ❌
s100.hdf5.file.open 1.01 1.04 +2.3% ▫️
s100.hdf5.open 3.38 3.83 +13.2% ❌
s100.pipeline.coverage.process 70.70 70.72 +0.0% ▫️
s100.pipeline.coverage.stage.read 38.80 39.35 +1.4% ▫️
s100.pipeline.coverage.stage.resolve 30.33 29.82 -1.7% ▫️
s100.render.coverage.build 180.91 184.59 +2.0% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.coverage.cells 437500.00 437500.00 +0.0% ▫️
s100.coverage.overview.level_selected 14.00 14.00 +0.0% ▫️
s100.coverage.pyramid.build.duration 7.07 6.85 -3.1% ▫️
s100.hdf5.read.bytes 8000000.00 8000000.00 +0.0% ▫️
s100.hdf5.read.duration 0.11 0.09 -19.6% ✅
s100.hdf5.read.duration 1.12 1.60 +42.0% ❌
s100.hdf5.read.duration 0.64 0.62 -3.0% ▫️
s100.pipeline.duration 15.41 13.10 -14.9% ✅
s100.pipeline.stage.duration 7.97 7.90 -0.8% ▫️
s100.pipeline.stage.duration 7.05 4.90 -30.6% ✅
s100.portrayal.cache.hit.count 7.00 7.00 +0.0% ▫️

s102-real-warm

Iteration statistics

Stat Baseline Candidate
Samples 5 5
Median (ms) 0.09 0.09
Baseline MAD (ms) 0.01 —
Δ median — -0.7%
z (Δ/MAD) — -0.08

s111-arrow-repeat

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 4.42 4.48
Baseline MAD (ms) 1.03 —
Δ median — +1.3%
z (Δ/MAD) — +0.05

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.dataset.open 72.06 71.95 -0.2% ▫️
s100.hdf5.dataset.read 35.84 38.49 +7.4% ❌
s100.hdf5.file.open 5.91 5.93 +0.3% ▫️
s100.hdf5.open 3.45 3.43 -0.4% ▫️
s100.pipeline.coverage.process 91.87 94.39 +2.7% ▫️
s100.pipeline.coverage.stage.read 79.13 78.17 -1.2% ▫️
s100.pipeline.coverage.stage.resolve 4.83 4.86 +0.7% ▫️

Metrics

Metric Baseline Candidate Delta Status
s100.catalogue.match.count 1.00 1.00 +0.0% ▫️
s100.coverage.cells 196630.00 196630.00 +0.0% ▫️
s100.coverage.overview.level_selected 0.00 0.00 N/A ▫️
s100.hdf5.read.bytes 22472.00 22472.00 +0.0% ▫️
s100.hdf5.read.duration 6.76 6.69 -1.0% ▫️
s100.hdf5.read.duration 7.11 7.76 +9.2% ❌
s100.hdf5.read.duration 0.69 0.70 +1.8% ▫️
s100.pipeline.duration 16.97 20.19 +18.9% ❌
s100.pipeline.stage.duration 14.51 15.07 +3.8% ▫️
s100.pipeline.stage.duration 0.88 0.86 -1.5% ▫️
s100.portrayal.cache.hit.count 70.00 70.00 +0.0% ▫️

s111-real-warm

Iteration statistics

Stat Baseline Candidate
Samples 5 5
Median (ms) 0.09 0.12
Baseline MAD (ms) 0.00 —
Δ median — +37.6%
z (Δ/MAD) — +29.73

s124-vector

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 0.35 0.34
Baseline MAD (ms) 0.02 —
Δ median — -4.2%
z (Δ/MAD) — -0.70

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.dataset.open 25.36 25.88 +2.1% ▫️
s100.featurecatalogue.parse 6.82 10.57 +54.9% ❌
s100.pipeline.vector.process 275.74 426.79 +54.8% ❌
s100.pipeline.vector.stage.assemble 7.05 7.09 +0.5% ▫️
s100.pipeline.vector.stage.feature_xml 11.92 11.73 -1.6% ▫️
s100.pipeline.vector.stage.rule_select 5.49 5.66 +3.2% ▫️
s100.pipeline.vector.stage.sort 0.31 0.32 +2.6% ▫️
s100.pipeline.vector.stage.viewing_groups 0.93 0.97 +3.9% ▫️
s100.pipeline.vector.stage.xslt 249.15 400.12 +60.6% ❌
s100.render.frame 3.79 3.66 -3.5% ▫️
s100.xslt.compile 182.03 301.97 +65.9% ❌
s100.xslt.transform 50.24 75.42 +50.1% ❌

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 54.75 54.30 -0.8% ▫️
s100.pipeline.features.in 7.00 7.00 +0.0% ▫️
s100.pipeline.stage.duration 1.40 1.40 -+0.0% ▫️
s100.pipeline.stage.duration 2.41 2.31 -4.4% ▫️
s100.pipeline.stage.duration 1.10 1.09 -1.5% ▫️
s100.pipeline.stage.duration 0.06 0.05 -12.8% ✅
s100.pipeline.stage.duration 0.09 0.07 -20.1% ✅
s100.pipeline.stage.duration 49.35 49.07 -0.6% ▫️
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 6.00 6.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 0.28 0.29 +3.9% ▫️
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 9.89 9.86 -0.3% ▫️

s201-vector

Iteration statistics

Stat Baseline Candidate
Samples 20 20
Median (ms) 0.49 0.49
Baseline MAD (ms) 0.02 —
Δ median — +0.4%
z (Δ/MAD) — +0.13

Spans (sum of all iterations)

Span Baseline (ms) Candidate (ms) Delta Status
s100.dataset.open 24.32 23.80 -2.1% ▫️
s100.featurecatalogue.parse 29.09 30.46 +4.7% ▫️
s100.pipeline.vector.process 666.13 678.36 +1.8% ▫️
s100.pipeline.vector.stage.assemble 3.38 3.40 +0.7% ▫️
s100.pipeline.vector.stage.feature_xml 40.32 40.33 +0.0% ▫️
s100.pipeline.vector.stage.rule_select 1.32 1.25 -4.8% ▫️
s100.pipeline.vector.stage.sort 0.13 0.14 +7.9% ❌
s100.pipeline.vector.stage.viewing_groups 0.57 0.58 +1.6% ▫️
s100.pipeline.vector.stage.xslt 618.94 631.20 +2.0% ▫️
s100.render.frame 4.58 4.57 -0.1% ▫️
s100.xslt.compile 482.01 493.17 +2.3% ▫️
s100.xslt.transform 134.29 135.38 +0.8% ▫️

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 7.00 7.00 +0.0% ▫️
s100.pipeline.duration 133.02 138.00 +3.7% ▫️
s100.pipeline.features.in 21.00 21.00 +0.0% ▫️
s100.pipeline.stage.duration 0.66 0.69 +3.2% ▫️
s100.pipeline.stage.duration 7.67 12.27 +60.0% ❌
s100.pipeline.stage.duration 0.27 0.25 -8.4% ▫️
s100.pipeline.stage.duration 0.02 0.02 +11.3% ❌
s100.pipeline.stage.duration 0.03 0.04 +26.5% ❌
s100.pipeline.stage.duration 123.97 124.30 +0.3% ▫️
s100.pipeline.stage.instructions.count 7.00 7.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 7.00 7.00 +0.0% ▫️
s100.pipeline.stage.instructions.count 7.00 7.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.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 0.40 0.42 +5.4% ❌
s100.render.instructions.processed.count 7.00 7.00 +0.0% ▫️
s100.render.styles.applied.count 14.00 14.00 +0.0% ▫️
s100.symbol.cache.hit.count 6.00 6.00 +0.0% ▫️
s100.symbol.cache.miss.count 1.00 1.00 +0.0% ▫️
s100.symbol.resolve.duration 0.01 0.01 -6.1% ▫️
s100.symbol.resolve.duration 0.22 0.24 +10.7% ❌
s100.xslt.transform.duration 27.08 25.85 -4.5% ▫️

Generated by EncDotNet.S100.PerfReport gate command

@philliphoff
philliphoff merged commit 9a4d2c0 into main Oct 12, 2026
14 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.

[Feature]: Adopt EncDotNet 0.8.0's ISO 8211 performance APIs in the S-101 reader, update applicator and S-57 translator

2 participants