ekp/postmortem/20260728-linear-text-builders.md
Kinneyzhang fd1210e557 fix: close repository audit findings
Complete task002 through task016 across cache correctness, editor lifecycle, C boundaries, build and release governance, dictionary provenance, performance, interactive workflows, tests, documentation, and final cleanup.
2026-07-28 22:43:10 +08:00

43 lines
1.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Measure Before Replacing Text Builders
## Context
The tokenizer appended each character to an accumulator string, dense
hyphen insertion rebuilt the whole prefix at every break, and the cache used
nil for both “absent” and “computed with no breaks.” These are familiar
smells, but ordinary paragraph performance did not prove they mattered.
An adversarial 1,0008,000-character benchmark established the boundary:
8× input grew tokenizer time 10.3× and dense insertion 11.5×. Repeated
no-break lookups also called the dictionary computation twice.
## Decision
Keep ownership in the existing tokenizer and hyphenator. Accumulate
fragments locally, join once at the point each complete value is emitted,
and use one private sentinel to distinguish a missing cache entry from a
cached nil. No general builder layer is introduced.
## Alternatives
- Leaving the loops unchanged was rejected after scaling and absolute time
both showed material cost.
- A reusable rope/builder abstraction was rejected because the two loops
have different owners and need only local lists.
- Moving either operation to C was rejected because text properties,
Unicode segmentation, and dictionary semantics remain Elisp-owned.
## Consequences
At 8,000 characters, source-mode tokenizer time fell from 3.133 s to
1.100 s and dense insertion from 0.945 s to 0.013 s. Growth across the
range is 6.3× and 7.7× respectively for 8× input. Negative hyphenation
results now reuse the cache. Exact output and text-property regressions
protect the representation change.
## Rollback
Revert the fragment builders together with their benchmark claims. Keep
the nil-cache sentinel and all output regressions unless evidence shows the
cache invalidation boundary itself is wrong.