zoo-bench · 2026-10-11 · AMD EPYC 7763 64-Core Processor

zoo-framework 0.6.0
性能评测

与 apscheduler、asyncio_pool、bare_thread、process_pool、thread_pool 共 5 个对照方案的同口径对比;全部数值由 zoo-bench 在本机重新测量、逐档公开,包括本框架输掉的档位。

原始数据:results/zoo-framework-0.6.0/20261011T091515Z.json

zoo-bench 报告

运行环境

项值
CPU 型号AMD EPYC 7763 64-Core Processor
逻辑核数4
平台Linux-x86_64
操作系统Linux 6.17.0-1022-azure(#22-Ubuntu SMP Mon Jul 27 17:24:03 UTC 2026)
PythonCPython 3.13.16
解释器/opt/hostedtoolcache/Python/3.13.16/x64/bin/python
GILdefault
被测框架(发行元数据)0.6.0
被测框架(模块 __version__)0.1.1-beta(仅附注,不作版本判据)
被测框架的驱动面世代上一代驱动面(workers 为可写属性,完成信号取自框架内部回调)
harnesszoo-bench 0.0.1 @ 9a42be24ac43f75e2e5d7b16434f91ba3d0717b6
复现命令zoo-bench run --framework zoo-framework==0.6.0

数据:运行环境

运行环境

运行环境(续)

以 dist_version(发行元数据)为版本真源;module_version 仅作附注

数据:运行环境

zoo-bench 报告

负载

  • 构成:单位工作 = JSON 序列化 + 反序列化 + 字符串拼接,重复若干次以达到目标耗时;档位由 matrix.yaml 的 body_tiers_us 声明
  • 负载是替身,不是真实 trace:形状接近“取一帧数据 -> 序列化 -> 解析 -> 字符串处理”这类业务动作,但仓库内没有真实样本,结论的适用性以此为前提

数据:负载

zoo-bench 报告

测量口径

  • 执行体耗时在同一次运行内埋点:由执行体在自身内部测量并回传,框架开销 =端到端 - 它。不做跨运行减法——两次运行的状态不同(缓存、频率、调度噪声),相减引入的是系统性偏差。
  • 预热不入统计:每个单元先跑 3 轮预热并丢弃,只统计随后的 30 轮正式采样;采样数等于「正式轮数 x 并发度」。
  • 绝对耗时不可跨运行比较:它只用于看量级;跨版本/跨机器要看的是同一次运行内的相对量(开销占比、相对各对照方案的倍数),它们对整体快慢不敏感。

数据:测量口径

zoo-bench 报告

结论摘要

  • 被测框架 zoo 的执行体时长达到约 10000 微秒 及以上时,其框架开销占端到端的比例降到 15% 以下;短于此档位,选用它的主要代价就是框架开销本身。
  • 并发度 1 下,所测档位内 apscheduler 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 4 下,所测档位内 apscheduler 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 16 下,所测档位内 apscheduler 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 64 下,所测档位内 apscheduler 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 1 下,所测档位内 asyncio_pool 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 4 下,所测档位内 asyncio_pool 始终快于被测框架——这类档位正是本报告的公开不利数据。

数据:结论摘要

结论摘要

结论摘要(续)

  • 并发度 16 下,所测档位内 asyncio_pool 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 64 下,所测档位内 asyncio_pool 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 1 下,所测档位内 bare_thread 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 4 下,所测档位内 bare_thread 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 16 下,所测档位内 bare_thread 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 64 下,所测档位内 bare_thread 始终快于被测框架——这类档位正是本报告的公开不利数据。
  • 并发度 1 下,所测档位内 process_pool 始终快于被测框架——这类档位正是本报告的公开不利数据。

数据:结论摘要

结论摘要

本章其余明细在全文里

幻灯片为了「一页一个结论」只放了本章的前 2 页;余下 6 页的逐单元数值、分位数与原始样本都在全文的同一章节里,逐字可核。

全文:同目录 report.md 的「结论摘要」章节

结论摘要 · 框架自身开销占比

5.28%

执行体 10000 微秒 时,zoo 的框架自身开销占比。
该档位有 5 个方案更低:apscheduler、asyncio_pool、bare_thread、process_pool、thread_pool。
同档对比:apscheduler 3.41%、asyncio_pool 1.51%、bare_thread 1.31%、process_pool 3.30%、thread_pool 0.64%

数据:zoo-bench「框架自身开销占比」· 并发度 1 · 执行体 10000 微秒 档

维度:延迟分位数与抖动

延迟分位数与抖动:并发度 1

并发度 1 · 端到端 / 并发度

执行体 40 微秒
zoo
606.25 微秒
apscheduler
293.74 微秒
asyncio_pool
145.49 微秒
bare_thread
143.75 微秒
process_pool
336.43 微秒
thread_pool
74.84 微秒
执行体 300 微秒
zoo
867.95 微秒
apscheduler
559.04 微秒
asyncio_pool
389.99 微秒
bare_thread
399.35 微秒
process_pool
606.27 微秒
thread_pool
338.26 微秒
被测框架对照方案条形 = 相对被测框架的倍数,1.0 为持平,越长越差

数据:zoo-bench「延迟分位数与抖动」· 并发度 1 · 逐单元数值与分位数见 report.md 的同一章节

维度:延迟分位数与抖动

延迟分位数与抖动:并发度 1(续)

并发度 1 · 端到端 / 并发度

执行体 2700 微秒
zoo
3.263 毫秒
apscheduler
2.989 毫秒
asyncio_pool
2.617 毫秒
bare_thread
2.690 毫秒
process_pool
3.015 毫秒
thread_pool
2.669 毫秒
执行体 10000 微秒
zoo
10.505 毫秒
apscheduler
9.889 毫秒
asyncio_pool
9.708 毫秒
bare_thread
9.552 毫秒
process_pool
9.702 毫秒
thread_pool
9.577 毫秒
被测框架对照方案条形 = 相对被测框架的倍数,1.0 为持平,越长越差

数据:zoo-bench「延迟分位数与抖动」· 并发度 1 · 逐单元数值与分位数见 report.md 的同一章节

zoo-bench 报告

维度:延迟分位数与抖动

端到端 / 并发度;分位数与相对离散度同表给出,只给中位数的度量不合格

并发度执行体档位(微秒)zooapschedulerasyncio_poolbare_threadprocess_poolthread_pool
140606.25 微秒293.74 微秒145.49 微秒143.75 微秒336.43 微秒74.84 微秒
1300867.95 微秒559.04 微秒389.99 微秒399.35 微秒606.27 微秒338.26 微秒
127003.263 毫秒2.989 毫秒2.617 毫秒2.690 毫秒3.015 毫秒2.669 毫秒
11000010.505 毫秒9.889 毫秒9.708 毫秒9.552 毫秒9.702 毫秒9.577 毫秒
440611.17 微秒267.20 微秒153.05 微秒158.85 微秒192.86 微秒95.11 微秒
4300866.98 微秒526.01 微秒428.07 微秒415.41 微秒283.82 微秒361.48 微秒
427003.307 毫秒3.003 毫秒2.800 毫秒2.693 毫秒1.390 毫秒2.676 毫秒
41000010.700 毫秒10.132 毫秒9.695 毫秒9.872 毫秒4.608 毫秒9.867 毫秒
1640610.25 微秒226.27 微秒138.37 微秒171.89 微秒161.53 微秒92.31 微秒
16300878.71 微秒484.41 微秒395.42 微秒423.77 微秒278.33 微秒353.51 微秒
1627003.306 毫秒2.977 毫秒2.744 毫秒2.704 毫秒1.410 毫秒2.790 毫秒

数据:维度:延迟分位数与抖动

维度:延迟分位数与抖动

维度:延迟分位数与抖动(续)

并发度执行体档位(微秒)zooapschedulerasyncio_poolbare_threadprocess_poolthread_pool
161000010.596 毫秒10.332 毫秒9.964 毫秒9.972 毫秒4.636 毫秒10.146 毫秒
6440565.92 微秒223.95 微秒120.73 微秒170.05 微秒196.54 微秒89.40 微秒
64300842.59 微秒507.24 微秒371.91 微秒425.03 微秒300.97 微秒355.32 微秒
6427003.323 毫秒2.949 毫秒2.832 毫秒2.764 毫秒1.354 毫秒2.788 毫秒
641000010.636 毫秒10.585 毫秒10.189 毫秒9.526 毫秒4.629 毫秒10.289 毫秒

逐单元数值(分位数、离散度、各轮原始样本)见文末「附录:全部数值」。

数据:维度:延迟分位数与抖动

维度:框架自身开销占比

框架自身开销占比:并发度 1

并发度 1 · 框架自身开销

执行体 40 微秒
zoo
88.13%
apscheduler
80.50%
asyncio_pool
66.60%
bare_thread
64.52%
process_pool
83.87%
thread_pool
40.99%
执行体 300 微秒
zoo
62.15%
apscheduler
46.08%
asyncio_pool
25.72%
bare_thread
26.40%
process_pool
49.32%
thread_pool
12.38%
被测框架对照方案条形 = 相对被测框架的倍数,1.0 为持平,越长越差

数据:zoo-bench「框架自身开销占比」· 并发度 1 · 逐单元数值与分位数见 report.md 的同一章节

维度:框架自身开销占比

框架自身开销占比:并发度 1(续)

并发度 1 · 框架自身开销

执行体 2700 微秒
zoo
17.04%
apscheduler
8.91%
asyncio_pool
4.87%
bare_thread
4.18%
process_pool
11.36%
thread_pool
1.76%
执行体 10000 微秒
zoo
5.28%
apscheduler
3.41%
asyncio_pool
1.51%
bare_thread
1.31%
process_pool
3.30%
thread_pool
0.64%
被测框架对照方案条形 = 相对被测框架的倍数,1.0 为持平,越长越差

数据:zoo-bench「框架自身开销占比」· 并发度 1 · 逐单元数值与分位数见 report.md 的同一章节

zoo-bench 报告

维度:框架自身开销占比

开销 = 端到端/并发度 - 同一次运行内实测的执行体耗时(不做跨运行减法)。带 — 的格:该并发度超出这台机器的并行能力,执行体自报耗时含超订的调度等待,与该行的每任务端到端不可比,故不给开销数字(端到端与吞吐见各自的维度)

并发度执行体档位(微秒)zooapschedulerasyncio_poolbare_threadprocess_poolthread_pool
14088.13%80.50%66.60%64.52%83.87%40.99%
130062.15%46.08%25.72%26.40%49.32%12.38%
1270017.04%8.91%4.87%4.18%11.36%1.76%
1100005.28%3.41%1.51%1.31%3.30%0.64%
44089.54%79.29%64.75%67.82%51.69%48.45%
430062.78%39.72%24.92%29.04%—14.55%
4270019.63%10.01%4.93%4.60%—2.23%
410000——————
1640——————
16300——————
162700——————

数据:维度:框架自身开销占比

维度:框架自身开销占比

维度:框架自身开销占比(续)

并发度执行体档位(微秒)zooapschedulerasyncio_poolbare_threadprocess_poolthread_pool
1610000——————
6440——————
64300——————
642700——————
6410000——————

逐单元数值(分位数、离散度、各轮原始样本)见文末「附录:全部数值」。

数据:维度:框架自身开销占比

维度:吞吐与并发伸缩

吞吐与并发伸缩:并发度 1

并发度 1 · 吞吐

执行体 40 微秒
zoo
1,649 任务/秒
apscheduler
3,404 任务/秒
asyncio_pool
6,873 任务/秒
bare_thread
6,956 任务/秒
process_pool
2,972 任务/秒
thread_pool
13,363 任务/秒
执行体 300 微秒
zoo
1,152 任务/秒
apscheduler
1,789 任务/秒
asyncio_pool
2,564 任务/秒
bare_thread
2,504 任务/秒
process_pool
1,649 任务/秒
thread_pool
2,956 任务/秒
被测框架对照方案条形 = 相对被测框架的倍数,1.0 为持平,越长越差

数据:zoo-bench「吞吐与并发伸缩」· 并发度 1 · 逐单元数值与分位数见 report.md 的同一章节

维度:吞吐与并发伸缩

吞吐与并发伸缩:并发度 1(续)

并发度 1 · 吞吐

执行体 2700 微秒
zoo
306 任务/秒
apscheduler
335 任务/秒
asyncio_pool
382 任务/秒
bare_thread
372 任务/秒
process_pool
332 任务/秒
thread_pool
375 任务/秒
执行体 10000 微秒
zoo
95 任务/秒
apscheduler
101 任务/秒
asyncio_pool
103 任务/秒
bare_thread
105 任务/秒
process_pool
103 任务/秒
thread_pool
104 任务/秒
被测框架对照方案条形 = 相对被测框架的倍数,1.0 为持平,越长越差

数据:zoo-bench「吞吐与并发伸缩」· 并发度 1 · 逐单元数值与分位数见 report.md 的同一章节

zoo-bench 报告

维度:吞吐与并发伸缩

吞吐 = 并发度 / 端到端中位数;随并发度是否继续上升即为伸缩性

并发度执行体档位(微秒)zooapschedulerasyncio_poolbare_threadprocess_poolthread_pool
1401649.53404.36873.26956.32972.413362.6
13001152.11788.82564.22504.11649.42956.3
12700306.5334.5382.1371.7331.7374.6
11000095.2101.1103.0104.7103.1104.4
4406544.914970.026136.125180.520740.742055.6
43004613.77604.49344.39629.014093.411065.7
427001209.41331.91428.51485.52878.61494.9
410000373.8394.8412.6405.2868.1405.4
164026218.870711.5115629.293082.799052.0173329.2
1630018208.433030.140462.937756.157486.645260.1
1627004839.35375.25831.55917.611345.15735.0

数据:维度:吞吐与并发伸缩

维度:吞吐与并发伸缩

维度:吞吐与并发伸缩(续)

并发度执行体档位(微秒)zooapschedulerasyncio_poolbare_threadprocess_poolthread_pool
16100001510.01548.61605.91604.53451.01577.0
6440113090.9285777.7530094.2376362.9325635.1715882.7
6430075956.6126173.2172085.1150577.9212645.4180117.2
64270019258.521702.322599.723154.047269.422956.6
64100006017.56046.26281.46718.213826.16220.2

逐单元数值(分位数、离散度、各轮原始样本)见文末「附录:全部数值」。

数据:维度:吞吐与并发伸缩

zoo-bench 报告

维度:开销归因

口径:把每任务端到端拆成提交侧 / 手交 / 执行体 / 回程四段,并在同一档位与并发度下与各对照方案逐段对照,回答「超出对照的部分落在哪一段」。它是诊断而非主证据:抽样一小批档位,且不与对照方案比总开销。手交为负不是错误:那表示提交调用还没返回、执行体就已经开跑——把建线程一类工作算进提交侧的方案就会这样(实测 bare_thread 手交 -343 微秒)。回程含完成信号的等待(排空返回前的最后一段),它与主测量是同一口径

状态:ok

本维度是诊断不是主证据:抽样的档位与并发度固定为一小批,不覆盖矩阵里的全部单元。并发度上界取机器的并行能力——超过它时量到的是争用;

抽样档位(微秒):40、10000;并发度:[1, 4];该机器并行能力:4

方案并发度档位(微秒)提交侧手交执行体回程状态
apscheduler140107.44 微秒91.43 微秒50.14 微秒39.97 微秒ok
apscheduler440110.35 微秒524.42 微秒55.76 微秒229.78 微秒ok
apscheduler110000138.62 微秒110.21 微秒9.664 毫秒49.29 微秒ok

数据:维度:开销归因

维度:开销归因

维度:开销归因(续)

方案并发度档位(微秒)提交侧手交执行体回程状态
apscheduler410000120.24 微秒12.806 毫秒14.493 毫秒9.873 毫秒ok
asyncio_pool14017.47 微秒26.05 微秒47.28 微秒58.04 微秒ok
asyncio_pool44018.91 微秒250.49 微秒53.92 微秒283.87 微秒ok
asyncio_pool11000023.03 微秒35.74 微秒9.574 毫秒84.68 微秒ok
asyncio_pool41000022.74 微秒12.394 毫秒10.117 毫秒10.093 毫秒ok
bare_thread140143.44 微秒-75.55 微秒51.49 微秒30.78 微秒ok
bare_thread440152.07 微秒-74.15 微秒50.96 微秒304.52 微秒ok
bare_thread1100005.171 毫秒-5093.61 微秒9.397 毫秒37.25 微秒ok
bare_thread4100005.180 毫秒-5085.51 微秒14.704 毫秒9.875 毫秒ok
process_pool140————not_measurable:执行体的起止时刻读不到——它没有在本进程里运行(跨进程档位无法这样分段)
process_pool440————not_measurable:执行体的起止时刻读不到——它没有在本进程里运行(跨进程档位无法这样分段)
process_pool110000————not_measurable:执行体的起止时刻读不到——它没有在本进程里运行(跨进程档位无法这样分段)
process_pool410000————not_measurable:执行体的起止时刻读不到——它没有在本进程里运行(跨进程档位无法这样分段)

数据:维度:开销归因

维度:开销归因

本章其余明细在全文里

幻灯片为了「一页一个结论」只放了本章的前 2 页;余下 9 页的逐单元数值、分位数与原始样本都在全文的同一章节里,逐字可核。

全文:同目录 report.md 的「维度:开销归因」章节

zoo-bench 报告

维度:调度语义的代价

口径:本维度采用内部开关对照(同一 workload 下语义全关 vs 逐个开启),不与对照方案横向比较——裸写法没有优先级/超时/重试的对应物,故只能回答“本框架的语义值多少钱”,不能回答“比裸写法贵多少”

状态:not_measured(结论在该次测量装着的「previous」代驱动面上得出)

在当前被测版本上,枚举出的语义项没有一项可测:要么其执行动作未实现,要么所在层无法执行反应器。按 design D7 的逃生口,此类项被剔除而非用近似状态代替

语义项层级探查方式可测证据 / 原因
超时派发层行为探查(按调度轮反复驱动,量在飞表摘除时刻)否判定存在但执行动作未实现:本探查按调度轮驱动、探查 worker 也声明了循环,调度轮确实跑过,故未摘除只能是判定本身没有执行动作——开启它只多算一次减法,量到的不是语义的代价
优先级事件层结构探查(检查执行所需的符号是否存在)否事件层执行反应器要先有 perform:EventWorker._execute 调 reactor.perform(workers/event_worker.py),而 EventReactor 只定义了 execute(reactor/event_reactor.py)——反应器一旦匹配即抛 AttributeError;EventPriorityCalculator 存在(fifo/node/event_fifo_node.py)但未接入 drain 循环——workers/event_worker.py 里“根据优先级排序”只有一句注释
重试事件层结构探查(检查执行所需的符号是否存在)否事件层执行反应器要先有 perform:EventWorker._execute 调 reactor.perform(workers/event_worker.py),而 EventReactor 只定义了 execute(reactor/event_reactor.py)——反应器一旦匹配即抛 AttributeError;retry_times 的默认 0 是干净的关闭态,但触发条件是“没有匹配到反应器”,而反应器路径本身不可执行

本结论按被测版本得出,坐标只对该版本成立;往 matrix.yaml 追加版本后须重跑本探查

数据:维度:调度语义的代价

zoo-bench 报告

维度:原生任务线:同一被测对象的三种执行形态

口径:该线独立测量:它不进入主矩阵的透视表与交叉点,其数值也不可与那些表里的对照方案横向比较

该线结论:not_applicable

被测框架不具备该能力(找不到这些符号:adaptive_params, dual_arm_worker, native_params, native_task_worker)——该线对此版本不适用,这不是失败

等价性门禁:未跑到(前置探查没走到这一步)

所测任务 modbus_rtu.parse_response——Modbus RTU 响应帧解析:输入是一条裸 RTU ADU 响应帧(不含任何传输层封装),其长度即该档位的帧字节

规模档位 R1、R8、R125(帧字节 7、21、255);并发度 1、4、16、64;每格预热 100 轮 + 采样 100 轮,每个并发度一个子进程(共 4 个)

数据:维度:原生任务线:同一被测对象的三种执行形态

zoo-bench 报告

被测框架在哪些档位更快

被测框架处于优势的档位(两侧差异大于该档位的带宽)。它与「公开的不利数据」出自同一份同运行内的相对比,只是一个取更快的、一个取更慢的——两者的覆盖面相同,故谁都挑不了档位。本节的缺席不构成不合格:分不出胜负或处处更慢时它就应当是空的

所测档位内未出现被测框架处于优势的情形。

数据:被测框架在哪些档位更快

公开的不利数据 · 归类

被测框架在 75 个档位上更慢,来自 5 个对照方案。

apscheduler · 13 个档位更快

最差 2.70x(并发 16 · 40 微秒)。全部档位:并发 1 · 40 微秒、并发 1 · 300 微秒、并发 1 · 2700 微秒、并发 1 · 10000 微秒、并发 4 · 40 微秒、并发 4 · 300 微秒、并发 4 · 10000 微秒、并发 16 · 40 微秒、并发 16 · 300 微秒、并发 16 · 2700 微秒、并发 64 · 40 微秒、并发 64 · 300 微秒、并发 64 · 2700 微秒

asyncio_pool · 16 个档位更快

最差 4.69x(并发 64 · 40 微秒)。全部档位:并发 1 · 40 微秒、并发 1 · 300 微秒、并发 1 · 2700 微秒、并发 1 · 10000 微秒、并发 4 · 40 微秒、并发 4 · 300 微秒、并发 4 · 2700 微秒、并发 4 · 10000 微秒、并发 16 · 40 微秒、并发 16 · 300 微秒、并发 16 · 2700 微秒、并发 16 · 10000 微秒、并发 64 · 40 微秒、并发 64 · 300 微秒、并发 64 · 2700 微秒、并发 64 · 10000 微秒

bare_thread · 16 个档位更快

最差 4.22x(并发 1 · 40 微秒)。全部档位:并发 1 · 40 微秒、并发 1 · 300 微秒、并发 1 · 2700 微秒、并发 1 · 10000 微秒、并发 4 · 40 微秒、并发 4 · 300 微秒、并发 4 · 2700 微秒、并发 4 · 10000 微秒、并发 16 · 40 微秒、并发 16 · 300 微秒、并发 16 · 2700 微秒、并发 16 · 10000 微秒、并发 64 · 40 微秒、并发 64 · 300 微秒、并发 64 · 2700 微秒、并发 64 · 10000 微秒

process_pool · 15 个档位更快

最差 3.78x(并发 16 · 40 微秒)。全部档位:并发 1 · 40 微秒、并发 1 · 300 微秒、并发 1 · 10000 微秒、并发 4 · 40 微秒、并发 4 · 300 微秒、并发 4 · 2700 微秒、并发 4 · 10000 微秒、并发 16 · 40 微秒、并发 16 · 300 微秒、并发 16 · 2700 微秒、并发 16 · 10000 微秒、并发 64 · 40 微秒、并发 64 · 300 微秒、并发 64 · 2700 微秒、并发 64 · 10000 微秒

thread_pool · 15 个档位更快

最差 8.10x(并发 1 · 40 微秒)。全部档位:并发 1 · 40 微秒、并发 1 · 300 微秒、并发 1 · 2700 微秒、并发 1 · 10000 微秒、并发 4 · 40 微秒、并发 4 · 300 微秒、并发 4 · 2700 微秒、并发 16 · 40 微秒、并发 16 · 300 微秒、并发 16 · 2700 微秒、并发 16 · 10000 微秒、并发 64 · 40 微秒、并发 64 · 300 微秒、并发 64 · 2700 微秒、并发 64 · 10000 微秒

数据:zoo-bench「公开的不利数据」· 逐档明细见其后的页与 report.md

zoo-bench 报告

公开的不利数据

被测框架处于劣势的档位(两侧差异大于该档位的带宽)。这部分缺失的报告不合格——一份只展示自己赢的报告,读者有理由认为它不可信。差异小于带宽的档位不在本节,而在「分不出胜负」那一节:那是判据的结果,不是把它们藏起来

对照方案并发度执行体档位(微秒)差距被测框架中位数
apscheduler140apscheduler 比 zoo 快 2.06x606.25 微秒
asyncio_pool140asyncio_pool 比 zoo 快 4.17x606.25 微秒
bare_thread140bare_thread 比 zoo 快 4.22x606.25 微秒
process_pool140process_pool 比 zoo 快 1.80x606.25 微秒
thread_pool140thread_pool 比 zoo 快 8.10x606.25 微秒
apscheduler1300apscheduler 比 zoo 快 1.55x867.95 微秒
asyncio_pool1300asyncio_pool 比 zoo 快 2.23x867.95 微秒
bare_thread1300bare_thread 比 zoo 快 2.17x867.95 微秒
process_pool1300process_pool 比 zoo 快 1.43x867.95 微秒
thread_pool1300thread_pool 比 zoo 快 2.57x867.95 微秒
apscheduler12700apscheduler 比 zoo 快 1.09x3.263 毫秒

数据:公开的不利数据

公开的不利数据

公开的不利数据(续)

对照方案并发度执行体档位(微秒)差距被测框架中位数
asyncio_pool12700asyncio_pool 比 zoo 快 1.25x3.263 毫秒
bare_thread12700bare_thread 比 zoo 快 1.21x3.263 毫秒
thread_pool12700thread_pool 比 zoo 快 1.22x3.263 毫秒
apscheduler110000apscheduler 比 zoo 快 1.06x10.505 毫秒
asyncio_pool110000asyncio_pool 比 zoo 快 1.08x10.505 毫秒
bare_thread110000bare_thread 比 zoo 快 1.10x10.505 毫秒
process_pool110000process_pool 比 zoo 快 1.08x10.505 毫秒
thread_pool110000thread_pool 比 zoo 快 1.10x10.505 毫秒
apscheduler440apscheduler 比 zoo 快 2.29x611.17 微秒
asyncio_pool440asyncio_pool 比 zoo 快 3.99x611.17 微秒
bare_thread440bare_thread 比 zoo 快 3.85x611.17 微秒
process_pool440process_pool 比 zoo 快 3.17x611.17 微秒
thread_pool440thread_pool 比 zoo 快 6.43x611.17 微秒

数据:公开的不利数据

公开的不利数据

公开的不利数据(续)

对照方案并发度执行体档位(微秒)差距被测框架中位数
apscheduler4300apscheduler 比 zoo 快 1.65x866.98 微秒
asyncio_pool4300asyncio_pool 比 zoo 快 2.03x866.98 微秒
bare_thread4300bare_thread 比 zoo 快 2.09x866.98 微秒
process_pool4300process_pool 比 zoo 快 3.05x866.98 微秒
thread_pool4300thread_pool 比 zoo 快 2.40x866.98 微秒
asyncio_pool42700asyncio_pool 比 zoo 快 1.18x3.307 毫秒
bare_thread42700bare_thread 比 zoo 快 1.23x3.307 毫秒
process_pool42700process_pool 比 zoo 快 2.38x3.307 毫秒
thread_pool42700thread_pool 比 zoo 快 1.24x3.307 毫秒
apscheduler410000apscheduler 比 zoo 快 1.06x10.700 毫秒
asyncio_pool410000asyncio_pool 比 zoo 快 1.10x10.700 毫秒
bare_thread410000bare_thread 比 zoo 快 1.08x10.700 毫秒
process_pool410000process_pool 比 zoo 快 2.32x10.700 毫秒

数据:公开的不利数据

公开的不利数据

公开的不利数据(续)

对照方案并发度执行体档位(微秒)差距被测框架中位数
apscheduler1640apscheduler 比 zoo 快 2.70x610.25 微秒
asyncio_pool1640asyncio_pool 比 zoo 快 4.41x610.25 微秒
bare_thread1640bare_thread 比 zoo 快 3.55x610.25 微秒
process_pool1640process_pool 比 zoo 快 3.78x610.25 微秒
thread_pool1640thread_pool 比 zoo 快 6.61x610.25 微秒
apscheduler16300apscheduler 比 zoo 快 1.81x878.71 微秒
asyncio_pool16300asyncio_pool 比 zoo 快 2.22x878.71 微秒
bare_thread16300bare_thread 比 zoo 快 2.07x878.71 微秒
process_pool16300process_pool 比 zoo 快 3.16x878.71 微秒
thread_pool16300thread_pool 比 zoo 快 2.49x878.71 微秒
apscheduler162700apscheduler 比 zoo 快 1.11x3.306 毫秒
asyncio_pool162700asyncio_pool 比 zoo 快 1.21x3.306 毫秒
bare_thread162700bare_thread 比 zoo 快 1.22x3.306 毫秒

数据:公开的不利数据

公开的不利数据

公开的不利数据(续)

对照方案并发度执行体档位(微秒)差距被测框架中位数
process_pool162700process_pool 比 zoo 快 2.34x3.306 毫秒
thread_pool162700thread_pool 比 zoo 快 1.19x3.306 毫秒
asyncio_pool1610000asyncio_pool 比 zoo 快 1.06x10.596 毫秒
bare_thread1610000bare_thread 比 zoo 快 1.06x10.596 毫秒
process_pool1610000process_pool 比 zoo 快 2.29x10.596 毫秒
thread_pool1610000thread_pool 比 zoo 快 1.04x10.596 毫秒
apscheduler6440apscheduler 比 zoo 快 2.53x565.92 微秒
asyncio_pool6440asyncio_pool 比 zoo 快 4.69x565.92 微秒
bare_thread6440bare_thread 比 zoo 快 3.33x565.92 微秒
process_pool6440process_pool 比 zoo 快 2.88x565.92 微秒
thread_pool6440thread_pool 比 zoo 快 6.33x565.92 微秒
apscheduler64300apscheduler 比 zoo 快 1.66x842.59 微秒
asyncio_pool64300asyncio_pool 比 zoo 快 2.27x842.59 微秒

数据:公开的不利数据

公开的不利数据

公开的不利数据(续)

对照方案并发度执行体档位(微秒)差距被测框架中位数
bare_thread64300bare_thread 比 zoo 快 1.98x842.59 微秒
process_pool64300process_pool 比 zoo 快 2.80x842.59 微秒
thread_pool64300thread_pool 比 zoo 快 2.37x842.59 微秒
apscheduler642700apscheduler 比 zoo 快 1.13x3.323 毫秒
asyncio_pool642700asyncio_pool 比 zoo 快 1.17x3.323 毫秒
bare_thread642700bare_thread 比 zoo 快 1.20x3.323 毫秒
process_pool642700process_pool 比 zoo 快 2.45x3.323 毫秒
thread_pool642700thread_pool 比 zoo 快 1.19x3.323 毫秒
asyncio_pool6410000asyncio_pool 比 zoo 快 1.04x10.636 毫秒
bare_thread6410000bare_thread 比 zoo 快 1.12x10.636 毫秒
process_pool6410000process_pool 比 zoo 快 2.30x10.636 毫秒
thread_pool6410000thread_pool 比 zoo 快 1.03x10.636 毫秒

数据:公开的不利数据

zoo-bench 报告

分不出胜负的档位

两侧分不出胜负的档位:差异小于该档位的带宽。带宽取自同一次运行内两侧各自的跨轮离散度(每任务中位数的标准差 / 中位数)之和,故它随样本变化,读者可用留档里的逐轮样本自行复核。它同样覆盖全部所测档位、逐项写明原因——本节不是藏东西的地方:把噪声级差异报成「快 1.00x」才是

判据:带宽 = 被测框架侧与对照侧各自的跨轮相对离散度之和;单侧的跨轮相对离散度 = 该单元逐轮的「每任务中位数」的标准差 / 中位数

本期带宽:1.6% 到 41.9%(随各档位的离散度不同而不同)。

对照方案并发度执行体档位(微秒)比值原因
process_pool127000.92x两侧差异 7.6% 小于带宽 21.2%,分不出胜负
apscheduler427000.91x两侧差异 9.2% 小于带宽 9.6%,分不出胜负
thread_pool4100000.92x两侧差异 7.8% 小于带宽 9.2%,分不出胜负
apscheduler16100000.98x两侧差异 2.5% 小于带宽 5.1%,分不出胜负
apscheduler64100001.00x两侧差异 0.5% 小于带宽 4.1%,分不出胜负

数据:分不出胜负的档位

zoo-bench 报告

口径局限与偏差来源

  • 被测层级:调度派发层:直接驱动 BaseWaiter.execute_service()(线程池模式),不走 Master 的完整运行循环——后者的服务循环每秒一次,会把延迟量级从微秒抬到秒。每提交一个任务走一次调度轮,故该轮的全部簿记都计在这一个任务头上;Master 的用法是每轮服务多个 worker,那份开销本会摊到多个任务上
  • 口径说明(apscheduler):APScheduler 的定时作业模型,含作业登记与触发判定成本;该库会吞掉作业内异常,本档已在 drain 时重新抛出。口径说明:该库不提供作业完成通知,故完成信号由本档的 Condition 给出,每任务一次通知的开销计入其端到端
  • 口径说明(asyncio_pool):asyncio 事件循环调度同步执行体(等价于 loop.run_in_executor),非原生协程并发;与线程池的差别是事件循环自身开销
  • 口径说明(bare_thread):每任务派生一个 threading.Thread,无池化、无复用;线程创建成本计入端到端。收集执行体自报耗时用无锁的 list.append(GIL 下本身原子)——插桩不得给某一档加别档没有的成本,否则对照就成了插桩的对照
  • 口径说明(process_pool):ProcessPoolExecutor:执行体与返回值跨进程序列化的成本计入端到端,与多线程档位不可直接等价比较

数据:口径局限与偏差来源

口径局限与偏差来源

口径局限与偏差来源(续)

  • 口径说明(thread_pool):concurrent.futures.ThreadPoolExecutor,池大小 = 并发度;线程复用、无任务队列语义
  • 口径说明(zoo):端到端终点为「worker 完成并在飞表注销」;框架其后的结果投递按世代分流:上一代的投递路径是坏的(dispatch 按 reactor_name 而非主题查响应器,每次调用必抛),完成信号只能取自框架内部回调;当前代该处已修好,完成信号取自框架自己的结果响应器。口径说明:完成信号由本档的 Condition 给出,每任务一次通知的开销计入其端到端;该方向的偏差使被测框架看起来更慢,即对被测框架不利而非有利
  • 不给出开销数字的组:以下 (适配器, 并发度) 组的并发度超过这次运行所在机器的并行能力:执行体自报的耗时里含超订带来的调度等待,与「墙钟 / 并发度」不是同一件事,相减的结果没有意义(实测出现过负值,并衍生出无意义的变化倍数)。故本报告对它们不给框架开销、也不给交叉点;端到端、吞吐与执行体自报值仍然有效,原始留档里的字段也一个没删。判据取自环境自述的逻辑核数,另有一条证据性兜底:算出来的开销为负同样判为不可读——框架只会加时间不会减时间
  • 原生任务线:未出结论:原生任务线结论为 not_applicable(被测框架不具备该能力(找不到这些符号:adaptive_params, dual_arm_worker, native_params, native_task_worker)——该线对此版本不适用,这不是失败)、未产出任何数字。它记在这里而不是并入自检:一条线的失败不得拖住其余版本的数据与主矩阵

数据:口径局限与偏差来源

口径局限与偏差来源

本章其余明细在全文里

幻灯片为了「一页一个结论」只放了本章的前 2 页;余下 1 页的逐单元数值、分位数与原始样本都在全文的同一章节里,逐字可核。

全文:同目录 report.md 的「口径局限与偏差来源」章节

zoo-bench 报告

加入你自己的对照

本 harness 的对照方案是开放的:实现 zoo_bench.adapters.BaseAdapter 的四个方法(setup / submit / drain / teardown),用 zoo_bench.adapters.registry.register 登记,或在 matrix.yaml 的 extra_modules 里列出你的模块路径——无需改动本仓库任何文件。你的实现会通过同一套等价性验证(提交 N 个执行体、断言全部执行且各执行一次),不通过的不会被采信。我们主动把这条路径写进报告:一份由被测框架维护者撰写、测量被测框架的报告,读者有理由怀疑对照被写慢或口径被挑选;让任何人能提交自己的对照,是这份报告可被质疑、也可被证伪的前提。

数据:加入你自己的对照

zoo-bench 报告

自检

  • 测量自检整体:通过
  • 进程隔离:{'parent_pid': 2921, 'child_pids': [3381, 3384, 3387, 3391, 3394, 3400, 3406, 3412, 3418, 3436, 3454, 3472, 3490, 3546, 3603, 3661, 3729, 3731, 3733, 3735, 3737, 3742, 3747, 3752, 3758, 3775, 3792, 3809, 3828, 3887, 3947, 4010, 4079, 4113, 4147, 4181, 4215, 4348, 4482, 4615, 4748, 5277, 5806, 6335, 6865, 8979, 11092, 13205, 15321, 15325, 15329, 15333, 15337, 15344, 15351, 15358, 15365, 15385, 15404, 15423, 15442, 15509, 15576, 15643, 15712, 15714, 15716, 15718, 15720, 15725, 15730, 15735, 15744, 15761, 15778, 15796, 15813, 15869, 15926, 16009, 16084, 16086, 16088, 16090, 16092, 16097, 16102, 16107, 16112, 16129, 16146, 16163, 1
  • 6182, 16247, 16312, 16378], 'all_distinct': True, 'none_equals_parent': True}

数据:自检

附录

每一页都可在全文里逐字复核

幻灯片为了「一页一个结论」而压缩了篇幅;被压缩的只有排版,没有数值。

  • 逐单元明细(分位数、离散度、每轮原始样本):同目录的 report.md
  • 图表(SVG 与 PNG):同目录的 figures/,另见 report.pdf
  • 原始留档:results/zoo-framework-0.6.0/20261011T091515Z.json
  • 本轮有效单元 96,失败单元 0

明细有一百多行,压进幻灯片等于让读者失去核对的手段。

← / → · space · R reset