diff --git a/docs/code-comments.md b/docs/code-comments.md index b541d93..5572e5a 100644 --- a/docs/code-comments.md +++ b/docs/code-comments.md @@ -73,7 +73,7 @@ | [src/runtime/api/tests.rs](../src/runtime/api/tests.rs) | API 集成回归。通过实际本地 HTTP 请求检查队列、候选替换、状态码、版本和完整文档发布。 | | [src/runtime/api/worker.rs](../src/runtime/api/worker.rs) | 唯一串行执行 VM 的 API worker。保留活跃运行时,另建 PUT 候选,并在候选完整成功后切换发布。 | | [src/runtime/endor_host.rs](../src/runtime/endor_host.rs) | 把 Aster 编译/执行与 Tessera 展示生命周期连接起来。Candidate 拥有 VM 与宿主根,ReplSession 保留实际运行中的全局环境。 | -| [src/runtime/endor_host/tests.rs](../src/runtime/endor_host/tests.rs) | 运行时集成回归与示例验收。测试经真实 Aster 前端、编译器、VM 和展示协议执行,不是手工伪造布局结果。 | +| [src/runtime/endor_host/tests.rs](../src/runtime/endor_host/tests.rs) | 说明全部运行时测试和辅助函数的场景/断言,并解释新主线性能基准的 DPI 分组、预热、三类计时边界和统计方式。 | | [src/runtime/endor_script.rs](../src/runtime/endor_script.rs) | 区分完整 Module 与顶层 Script,并保留输入源码位置。 | | [src/runtime/event_dispatch.rs](../src/runtime/event_dispatch.rs) | 托管事件与订阅的传播实现。Connection 持有回调引用,Event 保存目标、阶段与停止传播状态。 | | [src/runtime/events.rs](../src/runtime/events.rs) | 原生窗口输入到执行 worker 的纯数据传输。Input 只含窗口/会话/版本/Mount 身份及有限坐标。 | diff --git a/src/runtime/endor_host/tests.rs b/src/runtime/endor_host/tests.rs index e83a1ae..a9623be 100644 --- a/src/runtime/endor_host/tests.rs +++ b/src/runtime/endor_host/tests.rs @@ -8,12 +8,14 @@ use crate::document::{NamespaceState, RenderCommand}; const EXAMPLE: &str = include_str!("../../../examples/hello.endor"); const PAGE: &str = include_str!("../../../examples/page.endor"); -/// Opt-in release benchmark; run alone to avoid test-thread interference. +/// 可选性能基准:分别测世界 UI 和普通三维场景在 1x/2x DPI 下的相机交互更新、变更绘制和同列表缓存绘制。 +/// 默认 ignore,需在已确认的构建环境中以 release 单测试线程运行,避免其他测试干扰;下面命令仅为运行说明。 /// cargo test --release --locked scene_interaction_performance -- --ignored --nocapture --test-threads=1 #[test] #[ignore] fn scene_interaction_performance() { use std::time::Instant; + /// 对非空毫秒样本排序后返回均值、索引中位数和向上取整秩的 p95;调用方每组固定保留 30 次测量。 fn summary(mut values: Vec) -> String { values.sort_by(f64::total_cmp); format!( @@ -23,6 +25,7 @@ fn scene_interaction_performance() { values[(values.len() * 95).div_ceil(100) - 1] ) } + // 每个场景/DPI 组合创建全新会话与像素缓冲,避免上一组合的相机状态和缓存直接污染下一组。 for (name, source) in [ ("world-ui", include_str!("../../../examples/world-ui.endor")), ("scene3d", include_str!("../../../examples/scene3d.endor")), @@ -44,6 +47,7 @@ fn scene_interaction_performance() { let mut updates = Vec::new(); let mut draws = Vec::new(); let mut cached = Vec::new(); + // 连续做 33 轮,前三轮预热;每轮使用最新发布版本构造事件,避免基准测到过期输入拒绝。 for sample in 0..33 { let target = document .frame @@ -51,6 +55,7 @@ fn scene_interaction_performance() { .iter() .find(|mount| mount.scene3d_viewport) .unwrap(); + // 选当前帧第一个三维视口,小幅 orbit;带中心锚点使世界面板等坐标映射路径也有完整输入。 let input = crate::events::Input { window: 1, session: document.frame.session, @@ -63,6 +68,7 @@ fn scene_interaction_performance() { tab_drop: None, screen_position: None, }; + // update 只计派发与完整文档刷新;display_list 构造在后面的绘制计时范围之外。 let start = Instant::now(); document = session.dispatch(&input).unwrap().document.unwrap(); let update = start.elapsed().as_secs_f64() * 1000.; @@ -75,6 +81,7 @@ fn scene_interaction_performance() { height, ) .unwrap(); + // 第一次 render 测相机已变化时的绘制;立即用同一列表再画一次,单独统计缓存重用路径。 let draw = start.elapsed().as_secs_f64() * 1000.; let start = Instant::now(); crate::software_renderer::SoftwareRenderer::render( @@ -84,6 +91,7 @@ fn scene_interaction_performance() { height, ) .unwrap(); + // 三类样本按同一轮配对保存,仅舍弃预热数据,不改变真实执行的相机操作。 if sample >= 3 { updates.push(update); draws.push(draw); @@ -96,6 +104,7 @@ fn scene_interaction_performance() { summary(draws), summary(cached) ); + // 额外打印派生工作量指标辅助解释耗时,不把这些查询本身算进上面的三类样本。 for stat in ["measured", "arranged", "snapshotVisited"] { println!( "PERFSTAT {name} {stat}={}",