Skip to content

perf(engine): reuse immutable sub-list views when slicing paginated tables (F10)#147

Merged
DemchaAV merged 1 commit into
developfrom
perf/table-pagination-slice
Jun 9, 2026
Merged

perf(engine): reuse immutable sub-list views when slicing paginated tables (F10)#147
DemchaAV merged 1 commit into
developfrom
perf/table-pagination-slice

Conversation

@DemchaAV

@DemchaAV DemchaAV commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Finding 10 — table pagination stops re-copying the tail on every page split

A multi-page table is split page-by-page (NodeDefinitionSupport.splitTableTableLayoutSupport.sliceTablePreparedNode). Each split re-sliced the shrinking tail by List.copyOf-ing its row and row-height lists — even though resolveTableLayout already builds those lists immutably (List.copyOf). Because the tail is re-sliced on every continuation page, that copy made pagination O(rows × pages).

The body-only slice now reuses the immutable sub-list views directly (a subList of an immutable list is already unmodifiable, and the fragment layout is transient — emit reads individual rows into fragments, so nothing long-lived retains the view). The repeated-header path still concatenates a genuine new list and is unchanged.

Before/after — deterministic allocation probe (2,500-row / 68-page table)

warm compile allocation
before (List.copyOf slice) 11,155 KB
after (sub-list view) 9,851 KB
Δ −1,304 KB (−11.7%)

AFTER min = max = 9,851 KB — fully deterministic.

Byte-identity

Same rows, same order — the slice just stops copying. Proven by:

  • full verify green: 1151 tests, japicmp + architecture guards;
  • 75 table/pagination tests incl. visual-regression demo renders;
  • new TableSlicePaginationTest pins the invariant — a 120-row (≥3 page) table places every row on exactly one page across the chained re-slices.

No public API or behaviour change.

…ables

A table that spans many pages is split page-by-page; each split re-sliced the shrinking tail by List.copyOf-ing its already-immutable row and row-height lists, making continuation O(rows x pages). The body-only slice now reuses the immutable sub-list views directly -- byte-identical output, O(1) per split.

Warm compile allocation on a 2,500-row / 68-page table: 11,155 KB -> 9,851 KB (-11.7%, deterministic). All table layout, pagination, and visual-regression tests pass unchanged; adds TableSlicePaginationTest pinning the row-distribution invariant across chained re-slices.
@DemchaAV DemchaAV merged commit 468e751 into develop Jun 9, 2026
11 checks passed
@DemchaAV DemchaAV deleted the perf/table-pagination-slice branch June 9, 2026 09:15
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