GUITaboo运行开销与APE吞吐专项审计
本报告只分析2026-11-07已验收五App、15条60分钟Run,不重跑、不调用模型,也未修改Native、Provider、Prompt、调度或正式结果。
先回答七个问题
- 普通动作选择量:Pure合计12,042次,StartLux 10,988次,少1,054次(8.754%);Jev 10,067次,少1,975次(16.401%)。这是本轮五条不同App轨迹合计的观测吞吐差,不能直接当成实现性能降幅。ODK两模型反而比Pure分别多2.94%、1.81%。
- Scarlet Jev少三分之一:1,625 vs 2,432,下降33.18%。318次请求确实同步阻塞APE await累计1,273.566秒;Gateway发送前排队900.873秒,上游调用357.319秒。本地prepare排除await为69.869秒。20–30、40–50、50–60分钟分别只有180、176、179次普通选择,并对应299.9、352.9、287.6秒await归账。这是最明确的直接时间来源;不把1,273.6秒和900.9秒相加,后者位于请求内。
- Omni两组为什么都慢:StartLux少17.64%,Jev少19.02%;可测prepare仅141.593和180.303秒,分别占预算3.93%、5.01%,不能解释为全部18%左右吞吐差。prepare后至最终选择另有226.042/341.379秒混合区间,含普通APE选择;App异常为Pure 1、SL 7、Jev 1。现有证据无法给出全部因果分摊,未完成录音也不是已证实的吞吐原因。
- ActivityDiary Jev时间在哪:699.014秒同步await,其中Gateway排队410.307秒,上游276.846秒;本地prepare 86.464秒。前三个10分钟普通选择408/418/392,后三段降到204/202/158,后三段await归账191.2/199.8/248.6秒。该Jev Run没有App崩溃回执,不能归因为崩溃恢复。
- 成功率:SL 344/344、Jev 686/686均HTTP 200;429、非200、记录到的超时均0。保存答案的协议字段校验和Native解析/消费均分别344/344、686/686。HTTP成功、协议有效、消费成功都不代表Probe功能新颖或执行收益。另有20/48次缓存合成回复,不能算HTTP调用。
- 真正阻塞APE的GUITaboo开销:本轮1,030次请求全部明确标为
synchronous,另有主调用线程await计时,不是假设API延迟等于APE阻塞。SL五Run累计await415.839秒、本地prepare114.953秒;Jev为2,230.990/190.923秒。严格截到各Run60分钟后的prepare并集分别530.792/2,420.441秒,占各自18,000秒总预算2.949%/13.447%。这是已测直接阻塞区间,不是完整实现开销,也不能直接换算少执行动作数。 - 后续优先检查什么:首先检查Jev高频审核下Gateway发送准入等待如何经同步await阻塞APE;其次检查重复候选进入实际Pair/HTTP的阶段;再为Omni的prepare后选择混合区间与App恢复补充离线无法替代的细粒度计时需求。这里只提出检查优先级,不实施修复或改限速。
以上数字可从逐Run汇总、每分钟表、逐请求延迟、逐审核计时及Gateway最小字段快照复算。分母始终为本轮已验收Run,不补跑也不替换seed。
15条Run统一结果
单位秒;await与本地是prepare内部互斥子项。最后一列为严格60分钟内除prepare后的剩余时间,包含大量正常APE工作,不能称为额外开销。
| App | 条件 | 普通选择 | 每分钟 | 相对Pure | HTTP | await | 本地prepare | prepare后至选择混合 | 60分内prepare并集 | 剩余 |
|---|---|---|---|---|---|---|---|---|---|---|
| ODK Collect | Pure | 2316 | 38.60 | 0.00% | 0 | 0.000 | 0.000 | 0.000 | 0.000 | 3600.000 |
| ODK Collect | StartLux | 2384 | 39.73 | 2.94% | 7 | 9.873 | 0.863 | 6.135 | 10.736 | 3589.264 |
| ODK Collect | Jev | 2358 | 39.30 | 1.81% | 20 | 70.811 | 2.875 | 50.006 | 73.686 | 3526.314 |
| Wikipedia | Pure | 2307 | 38.45 | 0.00% | 0 | 0.000 | 0.000 | 0.000 | 0.000 | 3600.000 |
| Wikipedia | StartLux | 2156 | 35.93 | -6.55% | 26 | 35.369 | 4.210 | 12.916 | 39.578 | 3560.422 |
| Wikipedia | Jev | 2198 | 36.63 | -4.72% | 25 | 35.008 | 4.005 | 2.825 | 39.012 | 3560.988 |
| Scarlet Notes | Pure | 2432 | 40.53 | 0.00% | 0 | 0.000 | 0.000 | 0.000 | 0.000 | 3600.000 |
| Scarlet Notes | StartLux | 2217 | 36.95 | -8.84% | 74 | 109.616 | 41.206 | 9.596 | 150.822 | 3449.178 |
| Scarlet Notes | Jev | 1625 | 27.08 | -33.18% | 318 | 1273.566 | 69.869 | 35.452 | 1342.467 | 2257.533 |
| Omni Notes | Pure | 2597 | 43.28 | 0.00% | 0 | 0.000 | 0.000 | 0.000 | 0.000 | 3600.000 |
| Omni Notes | StartLux | 2139 | 35.65 | -17.64% | 97 | 114.423 | 27.170 | 226.042 | 141.593 | 3458.407 |
| Omni Notes | Jev | 2103 | 35.05 | -19.02% | 80 | 152.592 | 27.711 | 341.379 | 180.303 | 3419.697 |
| ActivityDiary | Pure | 2390 | 39.83 | 0.00% | 0 | 0.000 | 0.000 | 0.000 | 0.000 | 3600.000 |
| ActivityDiary | StartLux | 2092 | 34.87 | -12.47% | 140 | 146.559 | 41.504 | 10.623 | 188.063 | 3411.937 |
| ActivityDiary | Jev | 1783 | 29.72 | -25.40% | 243 | 699.014 | 86.464 | 113.960 | 784.973 | 2815.027 |
所有Run ID及原始ZIP引用见同名CSV。Probe选择为SL64、Jev87,其中Jev有1次执行失败,已确认执行仍为SL64、Jev86,共150;普通动作分母排除了Probe选择。
HTTP到Ledger的端到端漏斗
| 条件 | 正式HTTP | 200 | 协议有效 | 解析且消费 | 缓存合成 | 消费事件含缓存 | 候选Ledger写入事件含缓存 | 延迟P50秒 | P95 | P99 |
|---|---|---|---|---|---|---|---|---|---|---|
| StartLux | 344 | 344 | 344 | 344 | 20 | 364 | 706 | 1.042 | 2.048 | 2.560 |
| Jev | 686 | 686 | 686 | 686 | 48 | 734 | 1376 | 3.844 | 5.176 | 5.287 |
Native延迟分位数使用各HTTP保存的latency_ns,线性插值分位数。Ledger是候选级事件,不能与请求级数直接相减;候选可能写入PROBE、REPRESENTED或UNRESOLVED。已保存Native wire离线回放还核对1,030个请求、1,974个网络候选决策,聚合不匹配为0,见既有回放,未重新调用模型。
StartLux/Jev分别有34/34次相同fingerprint的后续发送,Native attempt>1也各34。冻结源码nextAttempt(fingerprint)是跨请求累计计数;这不是“34次失败重试”。本轮没有HTTP失败或失败后重试的证据。已发送未消费请求为0/0;消费事件多于HTTP数正是20/48次合成缓存回复。缓存命中后仍可能重复访问State,但不自动产生HTTP。
为什么约6秒限速会影响APE
冻结准入配置experiments/guitaboo-5app-1rep-baseline-comparison-20261107/admission/providers-before.json中Jev为rate_rpm=10,max_inflight=2。这限制Gateway上游发送准入,不是Native每动作固定sleep6秒。Scarlet Jev同Run相邻Gateway上游发送P50为6.063秒,ActivityDiary为6.068秒;排队总量分别900.873、410.307秒。队列可能同时含准入与并发等待,没有进一步细项,不能把全部队列逐毫秒归给rate limiter。
当前只读平台源码[HOME]/darwin-deploy/experiment_platform/lab_platform/provider.py的_acquire按last_sent检查60/rate_rpm,request循环等准入。这是当前实现旁证,不是逐字节冻结的当时部署快照。运行级结论来自冻结配置、Gateway同Host已落盘时间及Native同步await,三者一致。Gateway队列包含在HTTP等待内,不能重复累计。
Native保存async_arrival回执也不能证明APE异步继续运行:冻结JevSemanticReview.archiveOnArrival同样为同步请求登记后台写盘。应以每条JEV_REQUEST_SENT.wait_mode及SEMANTIC_WAIT_STARTED、SEMANTIC_REVIEW_TIMING.provider_wait_ns判断。本轮异步请求0、同步1,030。未来异步Run不能直接复用“HTTP累计延迟=APE阻塞”的结论。
导航、FUZZ与长停顿
| App | 条件 | FUZZ批次 | FUZZ至下一输入envelope并集秒 | 普通目标导航并集秒 | 明确含Probe目标路径数 | 含Probe目标路径并集秒 | App异常回执 |
|---|---|---|---|---|---|---|---|
| ODK Collect | Pure | 44 | 616.295 | 1118.511 | 0 | 0.000 | 0 |
| ODK Collect | StartLux | 53 | 742.373 | 878.823 | 1 | 1.318 | 0 |
| ODK Collect | Jev | 46 | 582.910 | 945.523 | 6 | 7.290 | 0 |
| Wikipedia | Pure | 50 | 709.768 | 709.656 | 0 | 0.000 | 1 |
| Wikipedia | StartLux | 38 | 457.184 | 785.126 | 4 | 8.715 | 1 |
| Wikipedia | Jev | 40 | 524.711 | 867.693 | 0 | 0.000 | 1 |
| Scarlet Notes | Pure | 55 | 738.376 | 1144.080 | 0 | 0.000 | 0 |
| Scarlet Notes | StartLux | 51 | 686.430 | 964.878 | 0 | 0.000 | 0 |
| Scarlet Notes | Jev | 28 | 386.768 | 515.882 | 10 | 12.549 | 0 |
| Omni Notes | Pure | 43 | 478.950 | 825.107 | 0 | 0.000 | 1 |
| Omni Notes | StartLux | 39 | 582.488 | 816.863 | 14 | 28.148 | 7 |
| Omni Notes | Jev | 42 | 545.746 | 673.863 | 10 | 12.652 | 1 |
| ActivityDiary | Pure | 50 | 618.686 | 1045.875 | 0 | 0.000 | 0 |
| ActivityDiary | StartLux | 43 | 649.487 | 952.535 | 1 | 1.148 | 5 |
| ActivityDiary | Jev | 29 | 446.878 | 627.758 | 6 | 9.620 | 0 |
复用已有分析器,只有同step/目标与PROBE_NAVIGATION_SELECTED有明确链接的路径才列为“含Probe目标”,不是从Remote Greedy次数推断。该路径可能同时带普通未执行目标,只有probe_only=True才提供进一步范围;即便含Probe目标,也不自动证明这条导航是反事实上额外增加的。navigation-cost.csv保留两者。全部路径与GUI/输入相交,不能与prepare等相加。
Scarlet Jev仅28批FUZZ,而Pure55;Activity Jev29而Pure50。“更多FUZZ导致Jev吞吐少”不受这些数量支持。FUZZ envelope含后续GUI/审核/恢复,不能当成精确FUZZ批次耗时。
各Run最大普通选择间隔在long-stalls.csv有前后操作、页面类、step、请求ID及原始行号。最长往往仅约25–32秒,且夹有FUZZ;高频1–5秒同步等待累积,同样可以显著降低吞吐,不一定表现为单次超长停顿。
- Jev 51.283–51.741分钟,step 1481→1482,普通选择间隔27.506秒。 前动作
type=MODEL_BACK;后动作type=MODEL_BACK。实测semantic prepare 0.001s(含await 0.000–0.000s); 区间内1批FUZZ,批末完成未埋点; 导航区间0.006s,与动作/GUI重叠。HTTP请求ID:[]。来源:run_95f70b23a59843b09110e90e309c467e.zip!device-output/native/sata-com.bijoysingh.quicknote-ape-sata-running-minutes-60/jev-events.jsonl:7734→run_95f70b23a59843b09110e90e309c467e.zip!device-output/native/sata-com.bijoysingh.quicknote-ape-sata-running-minutes-60/jev-events.jsonl:7742。不能将整个间隔归给相邻动作或模型。 - Jev 29.825–30.321分钟,step 1228→1229,普通选择间隔29.735秒。 前动作
type=MODEL_CLICK|activity=de.rampro.activitydiary.ui.main.MainActivity|class=android.widget.ImageButton|text=#8690306c|resource_id=|bounds=0,63,147,210;后动作type=MODEL_CLICK|activity=de.rampro.activitydiary.ui.generic.EditActivity|class=android.widget.ImageButton|text=#47c28800|resource_id=|bounds=0,63,147,210。区间内1批FUZZ,批末完成未埋点; 导航区间0.003s,与动作/GUI重叠。HTTP请求ID:[]。来源:run_2b38f68437b6480c8f26d01cec61b440.zip!device-output/native/sata-de.rampro.activitydiary-ape-sata-running-minutes-60/jev-events.jsonl:4324→run_2b38f68437b6480c8f26d01cec61b440.zip!device-output/native/sata-de.rampro.activitydiary-ape-sata-running-minutes-60/jev-events.jsonl:4332。不能将整个间隔归给相邻动作或模型。 - StartLux 42.278–42.740分钟,step 1530→1532,普通选择间隔27.721秒。 前动作
type=MODEL_BACK;后动作type=MODEL_BACK。实测semantic prepare 0.020s(含await 0.000–0.000s); 区间内1批FUZZ,批末完成未埋点。HTTP请求ID:[]。来源:run_0c300af1c9614168998ce1f37b6aadfe.zip!device-output/native/sata-it.feio.android.omninotes-ape-sata-running-minutes-60/jev-events.jsonl:6931→run_0c300af1c9614168998ce1f37b6aadfe.zip!device-output/native/sata-it.feio.android.omninotes-ape-sata-running-minutes-60/jev-events.jsonl:6946。不能将整个间隔归给相邻动作或模型。 - Jev 10.150–10.639分钟,step 415→423,普通选择间隔29.380秒。 前动作
type=MODEL_BACK;后动作type=MODEL_SCROLL_LEFT_RIGHT|activity=org.odk.collect.android.preferences.screens.ProjectPreferencesActivity|class=androidx.recyclerview.widget.RecyclerView|text=|resource_id=org.odk.collect.android:id/recycler_view|bounds=0,231,1080,2337。实测semantic prepare 22.348s(含await 21.590–21.590s); 导航区间0.089s,与动作/GUI重叠。HTTP请求ID:["semantic-21","semantic-22","semantic-23","semantic-24","semantic-26"]。来源:run_b4871490b9e84bbcb1a9b3464ca596fd.zip!device-output/native/sata-org.odk.collect.android-ape-sata-running-minutes-60/jev-events.jsonl:1514→run_b4871490b9e84bbcb1a9b3464ca596fd.zip!device-output/native/sata-org.odk.collect.android-ape-sata-running-minutes-60/jev-events.jsonl:1627。不能将整个间隔归给相邻动作或模型。
具体App与可复算入口

统计方法和证据边界
只读复用tools/guitaboo_postprocess.Source、已验收的15条Run统计与归档。正式APK-wide覆盖结果未改;每分钟首次方法来自METHOD观测,属于日志覆盖下界,不代替正式覆盖。计时主范围为各Run正式开始后的[0,3600);accepted原日志结束略越界,末尾普通选择与METHOD单列,不能强塞进第60分钟。
Native持续时间使用同一设备monotonic_ns差值。分钟定位使用该Run正式设备起点与wall-minus-monotonic中位偏移,偏移抖动约1–2毫秒。Gateway排队为同Hostsent_at-received_at,上游调用为同Hostcompleted_at-sent_at;不将Host和设备绝对时间相减。请求用Run ID、Native输入fingerprint与Gateway body SHA以及相同fingerprint下的发送顺序一一匹配,1,030/1,030成功;排除preflight。
semantic_prepare = provider_wait + local_prepare_excluding_wait,三者不能再次相加。prepare是主调用链进入审核到prepare返回的墙钟阻塞区间,本地部分也可能含worker等待/调度,并不等同CPU时间。post_prepare_selection还包含普通APE fallback选择,不能全部归为GUITaboo。导航、动作到GUI确认、FUZZ到下一输入、异常恢复以及后台写盘区间可能重叠,不以它们拼出3600秒饼图。
await有精确累计持续时长,但单次确切开始/结束仅由WAIT_STARTED和RESPONSE_CONSUMED包围。因此分钟CSV给物理占用上下界;按10分钟表的await与本地成本采用review结束分钟归账,不冒充精确占用分割。3600-prepare并集包含普通执行、GUI采集、等待、FUZZ、恢复及未埋点时间,不是GUITaboo未解释开销。
代码和复现
- JevRuntime.java:321–356和873–885行,prepare与post计时边界。
- JevSemanticReview.java:270–315行同步等待,512–515行await计时,529行起同步请求也登记arrival写盘;932行起attempt计数。
- JevTransport.java:64–82行消费与CountDownLatch。
- JevTiming.java、JevOutput.java:聚合末尾样本、嵌套及后台writer不能直接累计成主线程耗时。
python reports/guitaboo-probe-decision-review-20261107/performance-audit/build_performance.py
python reports/guitaboo-probe-decision-review-20261107/performance-audit/write_reports.py
第一命令读取既有ZIP/正式统计,Gateway只读快照存在时直接复用;缺少快照时仅用SQLitemode=ro查询指定15Run必要字段。第二命令只读本目录表格并生成本目录报告和图。版本为脚本SHA256,写入validation.json,不依赖当前未提交代码commit代表分析版本。