zoo-bench - 2026-10-11 - AMD EPYC 7763 64-Core Processor
Same-caliber comparison against 5 baselines: apscheduler, asyncio_pool, bare_thread, process_pool, thread_pool. Every number was re-measured on this machine by zoo-bench and published per tier, including the tiers the framework under test loses.
raw data: results/zoo-framework-0.7.1b0/20261011T091928Z.json
zoo-bench report
| item | value |
|---|---|
| CPU model | AMD EPYC 7763 64-Core Processor |
| logical cores | 4 |
| platform | Linux-x86_64 |
| operating system | Linux 6.17.0-1022-azure (#22-Ubuntu SMP Mon Jul 27 17:24:03 UTC 2026) |
| Python | CPython 3.13.16 |
| interpreter | /opt/hostedtoolcache/Python/3.13.16/x64/bin/python |
| GIL | default |
| framework under test (distribution metadata) | 0.7.1-beta |
| framework under test (module __version__) | 0.7.1-beta (footnote only, not the version criterion) |
| drive-surface generation of the framework under test | current-generation drive surface (scheduling core + scheduling model; the completion signal comes from the result reactor) |
| harness | zoo-bench 0.0.1 @ 9a42be24ac43f75e2e5d7b16434f91ba3d0717b6 |
| command to reproduce | zoo-bench run --framework zoo-framework==0.7.1b0 |
data: Run environment
Run environment
dist_version (the distribution metadata) is the source of truth; module_version is only a footnote
data: Run environment
zoo-bench report
data: Workload
zoo-bench report
data: Measurement methodology
zoo-bench report
data: Conclusion summary
Conclusion summary
data: Conclusion summary
Conclusion summary
For one conclusion per slide, only the first 2 slides of this section are shown; the remaining 8 slides of per-unit numbers, percentiles and raw samples sit in the same section of the full report, verbatim checkable.
full report: the "Conclusion summary" section of report.md in the same directory
Conclusion summary - framework overhead share
Framework overhead share of zoo at body tier 10000 microseconds.
2 baselines are lower at this tier: bare_thread, thread_pool.
same-tier comparison: apscheduler 3.67%, asyncio_pool 2.05%, bare_thread 1.36%, process_pool 3.15%, thread_pool 0.70%
data: zoo-bench "framework overhead share" at concurrency 1, body tier 10000 microseconds
Dimension: Latency percentiles and jitter
concurrency 1 - end-to-end / concurrency
data: zoo-bench "Latency percentiles and jitter" at concurrency 1 - per-unit numbers and percentiles are in the same section of report.md
Dimension: Latency percentiles and jitter
concurrency 1 - end-to-end / concurrency
data: zoo-bench "Latency percentiles and jitter" at concurrency 1 - per-unit numbers and percentiles are in the same section of report.md
zoo-bench report
end-to-end / concurrency; percentiles and relative spread are given in the same table - a metric that only gives the median is not acceptable
| concurrency | body tier (microseconds) | zoo | apscheduler | asyncio_pool | bare_thread | process_pool | thread_pool |
|---|---|---|---|---|---|---|---|
| 1 | 40 | 182.10 microseconds | 292.58 microseconds | 143.70 microseconds | 149.41 microseconds | 352.82 microseconds | 75.72 microseconds |
| 1 | 300 | 386.65 microseconds | 549.93 microseconds | 398.87 microseconds | 404.88 microseconds | 594.83 microseconds | 330.18 microseconds |
| 1 | 2700 | 2.736 milliseconds | 2.991 milliseconds | 2.778 milliseconds | 2.714 milliseconds | 2.951 milliseconds | 2.717 milliseconds |
| 1 | 10000 | 9.726 milliseconds | 9.741 milliseconds | 9.939 milliseconds | 9.438 milliseconds | 10.016 milliseconds | 9.708 milliseconds |
| 4 | 40 | 203.45 microseconds | 264.75 microseconds | 155.40 microseconds | 160.45 microseconds | 233.46 microseconds | 96.14 microseconds |
| 4 | 300 | 465.41 microseconds | 523.52 microseconds | 410.22 microseconds | 421.56 microseconds | 293.33 microseconds | 355.71 microseconds |
| 4 | 2700 | 2.884 milliseconds | 2.993 milliseconds | 2.762 milliseconds | 2.677 milliseconds | 1.389 milliseconds | 2.729 milliseconds |
| 4 | 10000 | 10.016 milliseconds | 9.919 milliseconds | 9.720 milliseconds | 9.673 milliseconds | 4.618 milliseconds | 9.759 milliseconds |
| 16 | 40 | 206.52 microseconds | 245.94 microseconds | 136.30 microseconds | 170.92 microseconds | 157.11 microseconds | 91.05 microseconds |
| 16 | 300 | 463.38 microseconds | 491.80 microseconds | 399.23 microseconds | 433.71 microseconds | 283.30 microseconds | 346.24 microseconds |
data: Dimension: Latency percentiles and jitter
Dimension: Latency percentiles and jitter
| concurrency | body tier (microseconds) | zoo | apscheduler | asyncio_pool | bare_thread | process_pool | thread_pool |
|---|---|---|---|---|---|---|---|
| 16 | 2700 | 2.875 milliseconds | 2.960 milliseconds | 2.844 milliseconds | 2.734 milliseconds | 1.430 milliseconds | 2.707 milliseconds |
| 16 | 10000 | 10.149 milliseconds | 10.207 milliseconds | 9.885 milliseconds | 9.515 milliseconds | 4.746 milliseconds | 9.680 milliseconds |
| 64 | 40 | 204.01 microseconds | 224.61 microseconds | 122.10 microseconds | 170.82 microseconds | 191.67 microseconds | 90.49 microseconds |
| 64 | 300 | 470.66 microseconds | 496.93 microseconds | 378.93 microseconds | 427.70 microseconds | 300.56 microseconds | 343.57 microseconds |
| 64 | 2700 | 2.891 milliseconds | 2.961 milliseconds | 2.754 milliseconds | 2.687 milliseconds | 1.376 milliseconds | 2.766 milliseconds |
| 64 | 10000 | 10.269 milliseconds | 10.691 milliseconds | 10.358 milliseconds | 9.802 milliseconds | 4.629 milliseconds | 10.397 milliseconds |
per-unit values (percentiles, spread, raw per-round samples) are in 'Appendix: all values' at the end.
data: Dimension: Latency percentiles and jitter
Dimension: Framework overhead share
concurrency 1 - framework overhead
data: zoo-bench "Framework overhead share" at concurrency 1 - per-unit numbers and percentiles are in the same section of report.md
Dimension: Framework overhead share
concurrency 1 - framework overhead
data: zoo-bench "Framework overhead share" at concurrency 1 - per-unit numbers and percentiles are in the same section of report.md
zoo-bench report
overhead = end-to-end / concurrency - the body duration measured within the same run (no cross-run subtraction). cells with -: that concurrency exceeds this machine's parallel capacity; the body's self-reported duration contains scheduling waits from oversubscription and is not comparable with the row's end-to-end per task, so no overhead figure is given (end-to-end and throughput live in their own dimensions)
| concurrency | body tier (microseconds) | zoo | apscheduler | asyncio_pool | bare_thread | process_pool | thread_pool |
|---|---|---|---|---|---|---|---|
| 1 | 40 | 71.79% | 80.15% | 65.83% | 64.64% | 84.46% | 40.53% |
| 1 | 300 | 43.97% | 44.02% | 26.35% | 26.00% | 49.83% | 12.18% |
| 1 | 2700 | 4.94% | 8.97% | 4.54% | 4.26% | 11.47% | 1.65% |
| 1 | 10000 | 1.68% | 3.67% | 2.05% | 1.36% | 3.15% | 0.70% |
| 4 | 40 | 73.41% | 79.88% | 65.20% | 68.16% | 59.90% | 48.10% |
| 4 | 300 | 33.89% | 40.02% | 26.02% | 29.31% | - | 15.90% |
data: Dimension: Framework overhead share
Dimension: Framework overhead share
| concurrency | body tier (microseconds) | zoo | apscheduler | asyncio_pool | bare_thread | process_pool | thread_pool |
|---|---|---|---|---|---|---|---|
| 4 | 2700 | 6.52% | 9.78% | 4.90% | 4.68% | - | 3.74% |
| 4 | 10000 | - | - | - | - | - | - |
| 16 | 40 | - | - | - | - | - | - |
| 16 | 300 | - | - | - | - | - | - |
| 16 | 2700 | - | - | - | - | - | - |
| 16 | 10000 | - | - | - | - | - | - |
| 64 | 40 | - | - | - | - | - | - |
| 64 | 300 | - | - | - | - | - | - |
| 64 | 2700 | - | - | - | - | - | - |
| 64 | 10000 | - | - | - | - | - | - |
per-unit values (percentiles, spread, raw per-round samples) are in 'Appendix: all values' at the end.
data: Dimension: Framework overhead share
Dimension: Throughput and concurrency scaling
concurrency 1 - throughput
data: zoo-bench "Throughput and concurrency scaling" at concurrency 1 - per-unit numbers and percentiles are in the same section of report.md
Dimension: Throughput and concurrency scaling
concurrency 1 - throughput
data: zoo-bench "Throughput and concurrency scaling" at concurrency 1 - per-unit numbers and percentiles are in the same section of report.md
zoo-bench report
throughput = concurrency / median end-to-end; whether it keeps rising with concurrency is the scaling behaviour
| concurrency | body tier (microseconds) | zoo | apscheduler | asyncio_pool | bare_thread | process_pool | thread_pool |
|---|---|---|---|---|---|---|---|
| 1 | 40 | 5491.5 | 3417.8 | 6958.7 | 6693.0 | 2834.3 | 13207.1 |
| 1 | 300 | 2586.3 | 1818.4 | 2507.1 | 2469.9 | 1681.2 | 3028.6 |
| 1 | 2700 | 365.5 | 334.3 | 360.0 | 368.5 | 338.9 | 368.0 |
| 1 | 10000 | 102.8 | 102.7 | 100.6 | 106.0 | 99.8 | 103.0 |
| 4 | 40 | 19661.0 | 15108.5 | 25740.3 | 24929.6 | 17133.9 | 41606.5 |
| 4 | 300 | 8594.6 | 7640.5 | 9750.8 | 9488.5 | 13636.3 | 11245.1 |
| 4 | 2700 | 1387.0 | 1336.6 | 1448.3 | 1494.0 | 2880.3 | 1465.9 |
| 4 | 10000 | 399.4 | 403.3 | 411.5 | 413.5 | 866.3 | 409.9 |
| 16 | 40 | 77474.6 | 65056.7 | 117388.0 | 93609.9 | 101836.3 | 175734.6 |
| 16 | 300 | 34528.5 | 32533.3 | 40077.0 | 36890.8 | 56477.9 | 46210.8 |
| 16 | 2700 | 5565.2 | 5405.6 | 5625.0 | 5852.3 | 11185.9 | 5909.9 |
data: Dimension: Throughput and concurrency scaling
Dimension: Throughput and concurrency scaling
| concurrency | body tier (microseconds) | zoo | apscheduler | asyncio_pool | bare_thread | process_pool | thread_pool |
|---|---|---|---|---|---|---|---|
| 16 | 10000 | 1576.5 | 1567.5 | 1618.7 | 1681.6 | 3371.6 | 1652.9 |
| 64 | 40 | 313716.1 | 284933.9 | 524166.3 | 374656.8 | 333912.8 | 707233.4 |
| 64 | 300 | 135978.9 | 128790.1 | 168896.4 | 149637.7 | 212933.5 | 186277.5 |
| 64 | 2700 | 22138.1 | 21617.7 | 23239.8 | 23821.1 | 46518.2 | 23134.1 |
| 64 | 10000 | 6232.3 | 5986.5 | 6178.8 | 6529.1 | 13825.1 | 6155.4 |
per-unit values (percentiles, spread, raw per-round samples) are in 'Appendix: all values' at the end.
data: Dimension: Throughput and concurrency scaling
zoo-bench report
scope: splits the per-task end-to-end into submit side / handoff / body / return and, at the same tier and concurrency, compares each segment against every baseline, answering 'which segment the excess falls on'. It is diagnostic, not the main evidence: it samples a small set of tiers, and does not compare total overhead against the baselines. A negative handoff is not an error: it means the submit call had not returned yet while the body was already running - schemes that count thread creation as submit side behave this way (measured: bare_thread handoff -343 microseconds). **The return segment includes waiting for th
e completion signal** (the last stretch before draining returns);
it shares the main measurement's scope
data: Dimension: Overhead attribution
Dimension: Overhead attribution
status: ok
this dimension is a diagnosis, not the main evidence: the sampled tiers and concurrencies are a fixed small batch, not the whole matrix. The concurrency ceiling is the machine's parallel capacity - beyond it, what is measured is contention;
sampled tiers (microseconds): 40, 10000; concurrency: [1, 4]; this machine's parallel capacity: 4
data: Dimension: Overhead attribution
Dimension: Overhead attribution
For one conclusion per slide, only the first 2 slides of this section are shown; the remaining 18 slides of per-unit numbers, percentiles and raw samples sit in the same section of the full report, verbatim checkable.
full report: the "Dimension: Overhead attribution" section of report.md in the same directory
zoo-bench report
scope: this dimension uses an internal switch comparison (same workload, semantics all off vs. enabled one by one) and does not compare across schemes - a bare writeup has no counterpart for priority / timeout / retry, so it can only answer 'what is this framework's semantics worth', not 'how much more expensive than a bare writeup'
status: ok (the conclusion was reached on the 'current' drive-surface generation installed during this measurement)
| semantics item | layer | how probed | measurable | evidence / reason |
|---|---|---|---|---|
| timeout | dispatch layer | behavioral probe (driven repeatedly through scheduling rounds; measures the moment the worker leaves the in-flight table) | yes | timeout reap observed: the worker left the in-flight table before the body ended (0.0123s) (body 0.15s, run_timeout 0.01s); judgment action at dispatch_core.py:365; what is in effect is observation and circuit-breaking (recording, marking unhealthy, removing the in-flight registration, stopping dispatch), not termination of the still-running worker - CPython cannot safely interrupt a running thread |
| priority | event layer | structural probe (checks whether the symbols required for execution exist) | no | not re-checked: this item's conclusion was reached on the 'previous' generation; taking it as this generation's fact asserts wiring in the report that the current generation does not have. Re-deriving it needs a probe design of its own (each item needs clean on/off states before it can be priced) |
| retry | event layer | structural probe (checks whether the symbols required for execution exist) | no | not re-checked: this item's conclusion was reached on the 'previous' generation; taking it as this generation's fact asserts wiring in the report that the current generation does not have. Re-deriving it needs a probe design of its own (each item needs clean on/off states before it can be priced) |
data: Dimension: The cost of scheduling semantics
Dimension: The cost of scheduling semantics
this conclusion was reached on the version under test and its coordinates hold for that version only; after appending a version to matrix.yaml, re-run this probe
data: Dimension: The cost of scheduling semantics
zoo-bench report
scope: this line is measured on its own: it enters neither the main matrix's pivot tables nor its crossings, and its numbers must not be read against the baseline adapters listed there
verdict: not_applicable
the framework under test has no such capability (symbols not found: adaptive_params, dual_arm_worker, native_params, native_task_worker) - this line does not apply to this version, and that is not a failure
equivalence gate: not run (the probe did not reach it)
loaded task modbus_rtu.parse_response - Modbus RTU response-frame parsing: the input is a bare RTU ADU response frame (no transport framing), and the tier's frame bytes are its length
data: Dimension: Native task line: three execution forms of the same subject
Dimension: Native task line: three execution forms of the same subject
tiers R1, R8, R125 (frame bytes 7, 21, 255); concurrencies 1, 4, 16, 64; each cell runs 100 warm-up plus 100 measured rounds, one child process per concurrency (4 in all)
data: Dimension: Native task line: three execution forms of the same subject
zoo-bench report
Tiers where the framework under test is ahead (the two sides differ by more than that tier's band). This comes from the same within-run comparison as the openly published unfavourable data - one side takes the faster tiers, the other the slower ones, so both cover the same ground and neither can pick its own tiers. This section being empty is not a failure: it should be empty when nothing is distinguishable or when the framework loses everywhere.
| baseline | concurrency | body tier (microseconds) | gap | median of the framework under test |
|---|---|---|---|---|
| apscheduler | 1 | 40 | the framework under test is 1.61x faster than apscheduler | 182.10 microseconds |
| process_pool | 1 | 40 | the framework under test is 1.94x faster than process_pool | 182.10 microseconds |
| apscheduler | 1 | 300 | the framework under test is 1.42x faster than apscheduler | 386.65 microseconds |
| process_pool | 1 | 300 | the framework under test is 1.54x faster than process_pool | 386.65 microseconds |
| apscheduler | 1 | 2700 | the framework under test is 1.09x faster than apscheduler | 2.736 milliseconds |
data: tiers where the framework under test is faster
tiers where the framework under test is faster
| baseline | concurrency | body tier (microseconds) | gap | median of the framework under test |
|---|---|---|---|---|
| process_pool | 1 | 2700 | the framework under test is 1.08x faster than process_pool | 2.736 milliseconds |
| asyncio_pool | 1 | 10000 | the framework under test is 1.02x faster than asyncio_pool | 9.726 milliseconds |
| process_pool | 1 | 10000 | the framework under test is 1.03x faster than process_pool | 9.726 milliseconds |
| apscheduler | 4 | 40 | the framework under test is 1.30x faster than apscheduler | 203.45 microseconds |
| apscheduler | 4 | 300 | the framework under test is 1.12x faster than apscheduler | 465.41 microseconds |
| apscheduler | 4 | 2700 | the framework under test is 1.04x faster than apscheduler | 2.884 milliseconds |
| apscheduler | 16 | 40 | the framework under test is 1.19x faster than apscheduler | 206.52 microseconds |
| apscheduler | 16 | 300 | the framework under test is 1.06x faster than apscheduler | 463.38 microseconds |
| apscheduler | 16 | 2700 | the framework under test is 1.03x faster than apscheduler | 2.875 milliseconds |
| apscheduler | 64 | 300 | the framework under test is 1.06x faster than apscheduler | 470.66 microseconds |
data: tiers where the framework under test is faster
Openly published unfavourable data - summary
worst 1.67x (concurrency 64 at 40 microseconds). All tiers: concurrency 1 at 40 microseconds, concurrency 4 at 40 microseconds, concurrency 4 at 300 microseconds, concurrency 4 at 2700 microseconds, concurrency 4 at 10000 microseconds, concurrency 16 at 40 microseconds, concurrency 16 at 300 microseconds, concurrency 16 at 10000 microseconds, concurrency 64 at 40 microseconds, concurrency 64 at 300 microseconds, concurrency 64 at 2700 microseconds
worst 1.27x (concurrency 4 at 40 microseconds). All tiers: concurrency 1 at 10000 microseconds, concurrency 4 at 40 microseconds, concurrency 4 at 300 microseconds, concurrency 4 at 2700 microseconds, concurrency 4 at 10000 microseconds, concurrency 16 at 40 microseconds, concurrency 16 at 300 microseconds, concurrency 16 at 2700 microseconds, concurrency 16 at 10000 microseconds, concurrency 64 at 40 microseconds, concurrency 64 at 300 microseconds, concurrency 64 at 2700 microseconds, concurrency 64 at 10000 microseconds
worst 2.22x (concurrency 64 at 10000 microseconds). All tiers: concurrency 4 at 300 microseconds, concurrency 4 at 2700 microseconds, concurrency 4 at 10000 microseconds, concurrency 16 at 40 microseconds, concurrency 16 at 300 microseconds, concurrency 16 at 2700 microseconds, concurrency 16 at 10000 microseconds, concurrency 64 at 300 microseconds, concurrency 64 at 2700 microseconds, concurrency 64 at 10000 microseconds
worst 2.41x (concurrency 1 at 40 microseconds). All tiers: concurrency 1 at 40 microseconds, concurrency 4 at 40 microseconds, concurrency 4 at 300 microseconds, concurrency 4 at 2700 microseconds, concurrency 4 at 10000 microseconds, concurrency 16 at 40 microseconds, concurrency 16 at 300 microseconds, concurrency 16 at 2700 microseconds, concurrency 16 at 10000 microseconds, concurrency 64 at 40 microseconds, concurrency 64 at 300 microseconds, concurrency 64 at 2700 microseconds
data: zoo-bench "published unfavorable data" - per-tier details follow on later slides and in report.md
zoo-bench report
Tiers where the framework under test is behind (the two sides differ by more than that tier's band). A report missing this part is not acceptable - a report that only shows where it wins gives the reader every reason to distrust it. Tiers whose difference is smaller than the band are not here but in the 'no winner' section: that is the verdict's outcome, not a place to hide things.
| baseline | concurrency | body tier (microseconds) | gap | median of the framework under test |
|---|---|---|---|---|
| asyncio_pool | 1 | 40 | asyncio_pool is 1.27x faster than zoo | 182.10 microseconds |
| thread_pool | 1 | 40 | thread_pool is 2.41x faster than zoo | 182.10 microseconds |
| bare_thread | 1 | 10000 | bare_thread is 1.03x faster than zoo | 9.726 milliseconds |
| asyncio_pool | 4 | 40 | asyncio_pool is 1.31x faster than zoo | 203.45 microseconds |
| bare_thread | 4 | 40 | bare_thread is 1.27x faster than zoo | 203.45 microseconds |
| thread_pool | 4 | 40 | thread_pool is 2.12x faster than zoo | 203.45 microseconds |
data: Openly published unfavourable data
Openly published unfavourable data
| baseline | concurrency | body tier (microseconds) | gap | median of the framework under test |
|---|---|---|---|---|
| asyncio_pool | 4 | 300 | asyncio_pool is 1.13x faster than zoo | 465.41 microseconds |
| bare_thread | 4 | 300 | bare_thread is 1.10x faster than zoo | 465.41 microseconds |
| process_pool | 4 | 300 | process_pool is 1.59x faster than zoo | 465.41 microseconds |
| thread_pool | 4 | 300 | thread_pool is 1.31x faster than zoo | 465.41 microseconds |
| asyncio_pool | 4 | 2700 | asyncio_pool is 1.04x faster than zoo | 2.884 milliseconds |
| bare_thread | 4 | 2700 | bare_thread is 1.08x faster than zoo | 2.884 milliseconds |
| process_pool | 4 | 2700 | process_pool is 2.08x faster than zoo | 2.884 milliseconds |
| thread_pool | 4 | 2700 | thread_pool is 1.06x faster than zoo | 2.884 milliseconds |
| asyncio_pool | 4 | 10000 | asyncio_pool is 1.03x faster than zoo | 10.016 milliseconds |
| bare_thread | 4 | 10000 | bare_thread is 1.04x faster than zoo | 10.016 milliseconds |
| process_pool | 4 | 10000 | process_pool is 2.17x faster than zoo | 10.016 milliseconds |
| thread_pool | 4 | 10000 | thread_pool is 1.03x faster than zoo | 10.016 milliseconds |
| asyncio_pool | 16 | 40 | asyncio_pool is 1.52x faster than zoo | 206.52 microseconds |
data: Openly published unfavourable data
Openly published unfavourable data
| baseline | concurrency | body tier (microseconds) | gap | median of the framework under test |
|---|---|---|---|---|
| bare_thread | 16 | 40 | bare_thread is 1.21x faster than zoo | 206.52 microseconds |
| process_pool | 16 | 40 | process_pool is 1.31x faster than zoo | 206.52 microseconds |
| thread_pool | 16 | 40 | thread_pool is 2.27x faster than zoo | 206.52 microseconds |
| asyncio_pool | 16 | 300 | asyncio_pool is 1.16x faster than zoo | 463.38 microseconds |
| bare_thread | 16 | 300 | bare_thread is 1.07x faster than zoo | 463.38 microseconds |
| process_pool | 16 | 300 | process_pool is 1.64x faster than zoo | 463.38 microseconds |
| thread_pool | 16 | 300 | thread_pool is 1.34x faster than zoo | 463.38 microseconds |
| bare_thread | 16 | 2700 | bare_thread is 1.05x faster than zoo | 2.875 milliseconds |
| process_pool | 16 | 2700 | process_pool is 2.01x faster than zoo | 2.875 milliseconds |
| thread_pool | 16 | 2700 | thread_pool is 1.06x faster than zoo | 2.875 milliseconds |
| asyncio_pool | 16 | 10000 | asyncio_pool is 1.03x faster than zoo | 10.149 milliseconds |
| bare_thread | 16 | 10000 | bare_thread is 1.07x faster than zoo | 10.149 milliseconds |
| process_pool | 16 | 10000 | process_pool is 2.14x faster than zoo | 10.149 milliseconds |
data: Openly published unfavourable data
Openly published unfavourable data
| baseline | concurrency | body tier (microseconds) | gap | median of the framework under test |
|---|---|---|---|---|
| thread_pool | 16 | 10000 | thread_pool is 1.05x faster than zoo | 10.149 milliseconds |
| asyncio_pool | 64 | 40 | asyncio_pool is 1.67x faster than zoo | 204.01 microseconds |
| bare_thread | 64 | 40 | bare_thread is 1.19x faster than zoo | 204.01 microseconds |
| thread_pool | 64 | 40 | thread_pool is 2.25x faster than zoo | 204.01 microseconds |
| asyncio_pool | 64 | 300 | asyncio_pool is 1.24x faster than zoo | 470.66 microseconds |
| bare_thread | 64 | 300 | bare_thread is 1.10x faster than zoo | 470.66 microseconds |
| process_pool | 64 | 300 | process_pool is 1.57x faster than zoo | 470.66 microseconds |
| thread_pool | 64 | 300 | thread_pool is 1.37x faster than zoo | 470.66 microseconds |
| asyncio_pool | 64 | 2700 | asyncio_pool is 1.05x faster than zoo | 2.891 milliseconds |
| bare_thread | 64 | 2700 | bare_thread is 1.08x faster than zoo | 2.891 milliseconds |
| process_pool | 64 | 2700 | process_pool is 2.10x faster than zoo | 2.891 milliseconds |
| thread_pool | 64 | 2700 | thread_pool is 1.04x faster than zoo | 2.891 milliseconds |
| bare_thread | 64 | 10000 | bare_thread is 1.05x faster than zoo | 10.269 milliseconds |
data: Openly published unfavourable data
Openly published unfavourable data
| baseline | concurrency | body tier (microseconds) | gap | median of the framework under test |
|---|---|---|---|---|
| process_pool | 64 | 10000 | process_pool is 2.22x faster than zoo | 10.269 milliseconds |
data: Openly published unfavourable data
zoo-bench report
Tiers where the two sides cannot be told apart: the difference is smaller than that tier's band. The band comes from the two sides' own across-round spread (stdev / median of the per-task medians) within the same run, so it varies with the sample and the reader can recompute it from the archived per-round samples. It also covers every measured tier and states a reason for each - this section is not a place to hide things: reporting noise-level differences as '1.00x faster' is.
criterion: band = the framework's own across-round relative spread plus the baseline's; a single side's across-round relative spread = stdev / median of that unit's per-round per-task medians
band this run: 0.9% to 24.7% (it varies with each tier's spread).
data: tiers with no winner
tiers with no winner
| baseline | concurrency | body tier (microseconds) | ratio | reason |
|---|---|---|---|---|
| bare_thread | 1 | 40 | 0.82x | the two sides differ by 18.0%, less than the band of 20.5% - no winner |
| asyncio_pool | 1 | 300 | 1.03x | the two sides differ by 3.2%, less than the band of 18.0% - no winner |
| bare_thread | 1 | 300 | 1.05x | the two sides differ by 4.7%, less than the band of 17.5% - no winner |
| thread_pool | 1 | 300 | 0.85x | the two sides differ by 14.6%, less than the band of 16.8% - no winner |
| asyncio_pool | 1 | 2700 | 1.02x | the two sides differ by 1.5%, less than the band of 3.3% - no winner |
| bare_thread | 1 | 2700 | 0.99x | the two sides differ by 0.8%, less than the band of 2.5% - no winner |
| thread_pool | 1 | 2700 | 0.99x | the two sides differ by 0.7%, less than the band of 1.5% - no winner |
| apscheduler | 1 | 10000 | 1.00x | the two sides differ by 0.2%, less than the band of 1.1% - no winner |
| thread_pool | 1 | 10000 | 1.00x | the two sides differ by 0.2%, less than the band of 1.7% - no winner |
| process_pool | 4 | 40 | 1.15x | the two sides differ by 14.7%, less than the band of 21.8% - no winner |
| apscheduler | 4 | 10000 | 0.99x | the two sides differ by 1.0%, less than the band of 5.0% - no winner |
| asyncio_pool | 16 | 2700 | 0.99x | the two sides differ by 1.1%, less than the band of 5.0% - no winner |
| apscheduler | 16 | 10000 | 1.01x | the two sides differ by 0.6%, less than the band of 1.6% - no winner |
data: tiers with no winner
tiers with no winner
For one conclusion per slide, only the first 2 slides of this section are shown; the remaining 1 slides of per-unit numbers, percentiles and raw samples sit in the same section of the full report, verbatim checkable.
full report: the "tiers with no winner" section of report.md in the same directory
zoo-bench report
data: caliber limitations and sources of bias
caliber limitations and sources of bias
data: caliber limitations and sources of bias
caliber limitations and sources of bias
For one conclusion per slide, only the first 2 slides of this section are shown; the remaining 5 slides of per-unit numbers, percentiles and raw samples sit in the same section of the full report, verbatim checkable.
full report: the "caliber limitations and sources of bias" section of report.md in the same directory
zoo-bench report
the baselines of this harness are open: implement the four methods of zoo_bench.adapters.BaseAdapter (setup / submit / drain / teardown), register with zoo_bench.adapters.registry.register, or list your module path in extra_modules of matrix.yaml - no file in this repository needs to change. Your implementation goes through the same equivalence verification (submit N bodies, assert all ran and each exactly once);
failing it means the data is not trusted. We deliberately write this path into the report: a report written by the framework's own maintainer, measuring that framework, gives every reason to suspect a slowed baseline or a chosen caliber; letting anyone submit their own baseline is what makes this report challengeable and falsifiable.
data: bring your own baseline
zoo-bench report
data: self-check
self-check
data: self-check
appendix
slides are compressed for one conclusion per page; only the layout is compressed, never the numbers.
results/zoo-framework-0.7.1b0/20261011T091928Z.jsonthe details run over a hundred rows; squeezing them into slides would strip readers of the means to verify.