From 81d32c7052d1c85b82b8fa290294cadf481e96eb Mon Sep 17 00:00:00 2001 From: Kinneyzhang Date: Mon, 27 Jul 2026 02:04:47 +0800 Subject: [PATCH] docs: record the paragraph-handle API as documented future work Assessed the C marshal cost (dominates range-justify: ~12 ms/width warm, mostly env extraction, not DP) and deliberately deferred the make_user_ptr handle API: it is a breaking 2.0 ABI change introducing C-side object lifetime, and the interactive paths already avoid the repeat marshal via the dp-cache. Documented in both DEVELOPER guides as the clear next step. Co-Authored-By: Claude Fable 5 --- DEVELOPER.md | 19 +++++++++++++++++++ DEVELOPER_ZH.md | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/DEVELOPER.md b/DEVELOPER.md index 5c401e7..1ee1203 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -246,6 +246,25 @@ produces a different layout on partial failure. The two engines are verified byte-identical by `ekp-test-c-parity-simple` / `ekp-test-c-parity-files` and the 300-case property fuzz. +### Future direction: a paragraph-handle API + +Each `ekp-c-break-with-arrays` call re-marshals the paragraph's +width-independent arrays (≈18·n `env` extractions). This is invisible +for a single justify but dominates `ekp-pixel-range-justify`, which +re-marshals the same arrays once per candidate width: with a warm +paragraph cache the C path still costs ≈12 ms per width, most of it +marshal, not DP (the DP is ≈2.5 ms for the whole sample). + +The fix is a `make_user_ptr` handle: `ekp-c-para-upload` copies the +arrays into a C struct once and returns a handle with a GC finalizer; +`ekp-c-break (handle, width)` then passes only the two width-dependent +scalars. It is deliberately **not** part of this release — it is a +breaking (2.0) ABI change introducing C-side object lifetime, and the +common interactive paths (single justify, `ekp-auto-justify-mode`) +already avoid the repeated marshal because they hit the dp-cache. It +is the clear next step whenever range search or very large batches +become a bottleneck. + ## 8. Hyphenation (ekp-hyphen.el) Liang's pattern algorithm, Pyphen-compatible: diff --git a/DEVELOPER_ZH.md b/DEVELOPER_ZH.md index eeff7bb..90a772f 100644 --- a/DEVELOPER_ZH.md +++ b/DEVELOPER_ZH.md @@ -212,6 +212,21 @@ C 端任何失败——NULL 结果、分配失败或非法参数——都回落 `ekp-test-c-parity-simple` / `ekp-test-c-parity-files` 及 300 例性质 fuzz 验证。 +### 未来方向:段落句柄 API + +每次 `ekp-c-break-with-arrays` 调用都会重新编组段落的宽度无关数组 +(约 18·n 次 `env` 提取)。单次 justify 时这无关紧要,但 +`ekp-pixel-range-justify` 会对每个候选宽度重新编组同一批数组:即便 +段落缓存已暖,C 路径每个宽度仍约 12 ms,其中大部分是编组而非 DP +(整篇样本的 DP 约 2.5 ms)。 + +解法是 `make_user_ptr` 句柄:`ekp-c-para-upload` 把数组一次性拷进 C +结构体并返回带 GC finalizer 的句柄,`ekp-c-break (handle, width)` 之后 +只传两个宽度相关标量。它**有意**不纳入本次发布——这是引入 C 端对象 +生命周期的破坏性(2.0)ABI 变更,而常见交互路径(单次 justify、 +`ekp-auto-justify-mode`)本就命中 dp-cache、避开了重复编组。当宽度 +搜索或超大批处理成为瓶颈时,这是明确的下一步。 + ## 8. 断词(ekp-hyphen.el) Liang 模式算法,兼容 Pyphen: