test: expose document preparation costs in scroll evaluation

This commit is contained in:
Kinneyzhang 2026-09-11 00:22:59 +08:00
parent db41a9b769
commit ecc490d8c6
4 changed files with 20 additions and 4 deletions

View File

@ -336,8 +336,8 @@ sample count, viewport height in lines, and an optional options plist.
By default, each file needs a scrollable root. By default, each file needs a scrollable root.
Content is fully cached before alternating one-line motions at the top and Content is fully cached before alternating one-line motions at the top and
midpoint. Results report mean/p95/max milliseconds, measurement-loop GC count/time, midpoint. Results report mean/p95/max milliseconds, measurement-loop GC count/time,
full root renders, node style full root renders, general document preparations, surface-plan construction,
visits, style computations, prefix rendering, full content materialization, and node style visits, style computations, prefix rendering, full content materialization, and
fresh-render parity; incomplete motion or changed fresh-render parity; incomplete motion or changed
output fails the run. The independent render comparison ignores runtime identity output fails the run. The independent render comparison ignores runtime identity
and zero-pixel spacers beside identical font faces; height carriers are retained. and zero-pixel spacers beside identical font faces; height carriers are retained.
@ -360,6 +360,8 @@ fresh oracle renders the committed input with its scroll offsets, preserving
callback and keymap identity. It does not reload companion application state. callback and keymap identity. It does not reload companion application state.
These checks cover Ebox publication work; use an actual displayed window when These checks cover Ebox publication work; use an actual displayed window when
measuring input delivery and Emacs redisplay latency. measuring input delivery and Emacs redisplay latency.
Inspect `:document-preparations` and `:surface-plans` to distinguish a viewport
publication from scrolling that still enters the general document update path.
Size data uses `(unit number)` with `px`, `%`, `vw`, `vh`, `ch`, and `lh`, plus Size data uses `(unit number)` with `px`, `%`, `vw`, `vh`, `ch`, and `lh`, plus
`calc`, `min`, `max`, and `clamp`. The [shared unit-constraint `calc`, `min`, `max`, and `clamp`. The [shared unit-constraint

View File

@ -45,7 +45,7 @@ plist。默认完全缓存根滚动内容再测量顶部和中间位置的往
`:prefix-renders`(实际前缀渲染)和 `:materializations`(完整内容生产)计数。 `:prefix-renders`(实际前缀渲染)和 `:materializations`(完整内容生产)计数。
已完成缓存的空操作不计入完整物化次数。 已完成缓存的空操作不计入完整物化次数。
结果报告 mean/p95/max 毫秒、采样循环的 GC 次数/耗时、完整根渲染、样式计算及缓存生产次数,并与独立渲染已提交输入、 结果报告 mean/p95/max 毫秒、采样循环的 GC 次数/耗时、完整根渲染、通用文档准备、surface 计划构造、样式计算及缓存生产次数,并与独立渲染已提交输入、
恢复其滚动位置后的结果比较。比较保留 callback 和 keymap 身份,不重新加载业务 恢复其滚动位置后的结果比较。比较保留 callback 和 keymap 身份,不重新加载业务
状态;移动未完成或绘制不一致都会失败。测试使用临时 buffer并清理挂载、advice 状态;移动未完成或绘制不一致都会失败。测试使用临时 buffer并清理挂载、advice
和定时器,不改变现有预览。测量包含 Ebox/TP 发布,不包含 GUI 输入传递、原生窗口 和定时器,不改变现有预览。测量包含 Ebox/TP 发布,不包含 GUI 输入传递、原生窗口

View File

@ -247,6 +247,7 @@ No files, windows, buffers, or persistent render state are modified."
"Measure STEPS one-line scrolls of REGION-ID. "Measure STEPS one-line scrolls of REGION-ID.
Alternate cached motion by default; COLD advances without retracing prior rows." Alternate cached motion by default; COLD advances without retracing prior rows."
(let ((root-renders 0) (node-styles 0) (style-computations 0) (let ((root-renders 0) (node-styles 0) (style-computations 0)
(document-preparations 0) (surface-plans 0)
(prefix-renders 0) (materializations 0) (prefix-renders 0) (materializations 0)
(deadline (+ (float-time) 30)) (deadline (+ (float-time) 30))
samples installed gc-start gc-time-start) samples installed gc-start gc-time-start)
@ -254,6 +255,10 @@ Alternate cached motion by default; COLD advances without retracing prior rows."
(progn (progn
(dolist (entry (dolist (entry
(list (list
(cons 'ebox-incremental-prepare-scoped-commit
(lambda (&rest _) (cl-incf document-preparations)))
(cons 'ebox-surface--surface-plan
(lambda (&rest _) (cl-incf surface-plans)))
(cons 'ebox-surface--render-candidate (cons 'ebox-surface--render-candidate
(lambda (&rest _) (cl-incf root-renders))) (lambda (&rest _) (cl-incf root-renders)))
(cons 'ebox-surface--apply-node-style (cons 'ebox-surface--apply-node-style
@ -293,6 +298,8 @@ Alternate cached motion by default; COLD advances without retracing prior rows."
samples 0.95) samples 0.95)
:max-ms (apply #'max samples) :max-ms (apply #'max samples)
:root-renders root-renders :node-styles node-styles :root-renders root-renders :node-styles node-styles
:document-preparations document-preparations
:surface-plans surface-plans
:style-computations style-computations :style-computations style-computations
:prefix-renders prefix-renders :materializations materializations)) :prefix-renders prefix-renders :materializations materializations))
(dolist (entry installed) (dolist (entry installed)
@ -625,6 +632,8 @@ Return bounded plists with :mode, semantic :region-id, :start-offset,
visits, style computations, and fresh-render parity for each position. visits, style computations, and fresh-render parity for each position.
:prefix-renders counts calls to the bounded scroll source renderer; :prefix-renders counts calls to the bounded scroll source renderer;
:materializations counts full-content producer invocations during samples. :materializations counts full-content producer invocations during samples.
:document-preparations counts general scoped document preparation;
:surface-plans counts construction of full surface publication plans.
:position is top/middle for cached samples or cold for advancing samples. :position is top/middle for cached samples or cold for advancing samples.
:max-offset is nil unless the selected content is fully materialized. :max-offset is nil unless the selected content is fully materialized.
The oracle independently renders the committed snapshot, preserving opaque The oracle independently renders the committed snapshot, preserving opaque
@ -735,7 +744,7 @@ Each sample loop checks a 30-second deadline between motions."
measurement))) measurement)))
(princ (princ
(format (format
"%s scroll %s %s mean=%.3fms p95=%.3fms max=%.3fms gc=%d/%.3fms roots=%d node-styles=%d style-computations=%d prefix-renders=%d materializations=%d parity=%S\n" "%s scroll %s %s mean=%.3fms p95=%.3fms max=%.3fms gc=%d/%.3fms roots=%d document-preparations=%d surface-plans=%d node-styles=%d style-computations=%d prefix-renders=%d materializations=%d parity=%S\n"
(if parity "PASS" "FAIL") (if parity "PASS" "FAIL")
(file-name-nondirectory file) position (file-name-nondirectory file) position
(plist-get measurement :mean-ms) (plist-get measurement :mean-ms)
@ -744,6 +753,8 @@ Each sample loop checks a 30-second deadline between motions."
(plist-get measurement :gc-count) (plist-get measurement :gc-count)
(plist-get measurement :gc-ms) (plist-get measurement :gc-ms)
(plist-get measurement :root-renders) (plist-get measurement :root-renders)
(plist-get measurement :document-preparations)
(plist-get measurement :surface-plans)
(plist-get measurement :node-styles) (plist-get measurement :node-styles)
(plist-get measurement :style-computations) (plist-get measurement :style-computations)
(plist-get measurement :prefix-renders) (plist-get measurement :prefix-renders)

View File

@ -447,6 +447,7 @@
(should (plist-get report :fresh-render-parity)) (should (plist-get report :fresh-render-parity))
(should (= (plist-get report :steps) 3)) (should (= (plist-get report :steps) 3))
(dolist (key '(:mean-ms :p95-ms :max-ms :root-renders (dolist (key '(:mean-ms :p95-ms :max-ms :root-renders
:document-preparations :surface-plans
:node-styles :style-computations :node-styles :style-computations
:prefix-renders :materializations)) :prefix-renders :materializations))
(should (>= (plist-get report key) 0)))) (should (>= (plist-get report key) 0))))
@ -470,6 +471,8 @@
(functions (functions
(mapcar (lambda (symbol) (cons symbol (symbol-function symbol))) (mapcar (lambda (symbol) (cons symbol (symbol-function symbol)))
'(ebox-surface--render-candidate '(ebox-surface--render-candidate
ebox-incremental-prepare-scoped-commit
ebox-surface--surface-plan
ebox-surface--apply-node-style ebox-surface--apply-node-style
ebox-surface--compute-node-style ebox-surface--compute-node-style
ebox--render-scroll-window-source ebox--render-scroll-window-source