Benchmarks
Workloads
Kernel startup
Results
Time from starting a kernel to the result of its first trivial cell, in an empty directory and in a Composer project whose autoloader loads phibble, phplyr, and phiz.
- Workload
- One kernel start and one trivial cell
One kernel start and one trivial cell: elapsed time per implementation and case, median of 20 runs. Memory not measured.
no autoloader, warm cache
| Implementation | Elapsed time | Fastest – slowest run |
|---|---|---|
| juphyter kernel | 419 ms | 390 ms – 472 ms |
| PHP engine alone | 19.6 ms | 18.8 ms – 20.6 ms |
| python3 ipykernel | 381 ms | 364 ms – 430 ms |
phibble, phplyr, and phiz autoloaded, warm cache
| Implementation | Elapsed time | Fastest – slowest run |
|---|---|---|
| juphyter kernel | 427 ms | 390 ms – 474 ms |
| PHP engine alone | 23.0 ms | 22.5 ms – 25.7 ms |
no autoloader, cold cache
| Implementation | Elapsed time | Fastest – slowest run |
|---|---|---|
| juphyter kernel | 616 ms | 521 ms – 676 ms |
| PHP engine alone | 63.2 ms | 62.0 ms – 127 ms |
| python3 ipykernel | 494 ms | 447 ms – 567 ms |
phibble, phplyr, and phiz autoloaded, cold cache
| Implementation | Elapsed time | Fastest – slowest run |
|---|---|---|
| juphyter kernel | 598 ms | 515 ms – 695 ms |
| PHP engine alone | 68.1 ms | 66.0 ms – 70.5 ms |
Methods
- Implementations
- juphyter kernel: php kernel through jupyter_client; ipykernel transport and PHP engine; PHP engine alone: php bin/juphyter engine over its Unix socket; no Jupyter; python3 ipykernel: stock ipykernel Python kernel
- Machine
- 2 AMD Zen 5 cores, 7.8 GB RAM, Linux
- Software
- PHP 8.5.12, juphyter v0.1.1-14-g058bee5, Python 3.14.10, ipykernel 7.4.0, jupyter_client 8.10.0, pyzmq 27.2.0, phibble 0.5.3, phiz 0.5.2, phplyr 0.4.5
- Threads
- 1
- Repetitions
- 20 timed runs
- Statistic
- Median over the timed runs
- Time measure
- Elapsed time, in ms
- Timing boundaries
- Kernels: from KernelManager.start_kernel() to the first cell's execute_reply and idle status. PHP engine alone: from spawning the PHP process to the engine's ok event. Kernel shutdown excluded. Cold cases: page cache emptied with drop_caches before each repetition. Warm cases: one warmup run.
- Time spent in
- PHP engine alone: the PHP process, including PHP startup, the engine, the autoloader, and the cell. juphyter kernel minus PHP engine alone: jupyter_client, ipykernel, and the Python transport.
- Cache
- Warm cases: warm; Cold cases: cold
- Memory metric
- Not measured
- Recorded
- 2026-11-01, commit 058bee5
Reproduction
bench/setup
bench/run startup
- Raw record
- site/benchmarks/kernel-startup.json
- Source
- bench/startup.py
Cell round trip
Results
Time per cell for 1,000 trivial cells in one session, and for 100 cells whose value is a 1,000-row phibble data frame formatted into its MIME bundle. Formatting is also timed without a kernel. The text and HTML representations each render the first 10 rows.
- Workload
- 1,000 trivial cells; 100 cells returning a 1,000-row, 5-column data frame
1,000 trivial cells; 100 cells returning a 1,000-row, 5-column data frame: elapsed time per cell, peak resident set size, and PHP allocator peak per implementation and case, median of 5 runs.
1,000 trivial cells
| Implementation | Elapsed time per cell | Fastest – slowest run | Peak resident set size | PHP allocator peak |
|---|---|---|---|---|
| juphyter kernel | 3.01 ms | 3.01 ms – 3.03 ms | 34.4 MiB | 14.0 MiB |
| PHP engine alone | 0.121 ms | 0.121 ms – 0.122 ms | not measured | 14.0 MiB |
| python3 ipykernel | 3.92 ms | 3.90 ms – 3.94 ms | not measured | not measured |
1,000-row data frame
| Implementation | Elapsed time per cell | Fastest – slowest run | Peak resident set size | PHP allocator peak |
|---|---|---|---|---|
| juphyter kernel | 3.29 ms | 3.24 ms – 3.30 ms | not measured | not measured |
| PHP engine alone | 0.356 ms | 0.352 ms – 0.359 ms | not measured | not measured |
| juphyter formatter, no kernel | 0.188 ms | 0.184 ms – 0.189 ms | not measured | not measured |
| phibble text output, no kernel | 0.137 ms | 0.137 ms – 0.138 ms | not measured | not measured |
Methods
- Implementations
- juphyter kernel: php kernel through jupyter_client; ipykernel transport and PHP engine; PHP engine alone: php bin/juphyter engine over its Unix socket; no Jupyter; python3 ipykernel: stock ipykernel Python kernel; cell 1; juphyter formatter, no kernel: Juphyter\Display\Registry::default()->format($frame) in one PHP process; phibble text output, no kernel: (string) $frame in one PHP process
- Machine
- 2 AMD Zen 5 cores, 7.8 GB RAM, Linux
- Software
- PHP 8.5.12, juphyter v0.1.1-14-g058bee5, Python 3.14.10, ipykernel 7.4.0, jupyter_client 8.10.0, pyzmq 27.2.0, phibble 0.5.3, phiz 0.5.2, phplyr 0.4.5
- Threads
- 1
- Repetitions
- 5 timed runs
- Statistic
- Median over the timed runs
- Time measure
- Elapsed time per cell, in ms
- Timing boundaries
- Kernels: from execute_request to execute_reply and idle status. PHP engine alone: from writing the request to the socket to the engine's ok event. No-kernel rows: hrtime around the expression. Each repetition is a new session with 20 trivial or 3 data-frame warmup cells. Value: median of the per-session median times. Data-frame construction excluded.
- Time spent in
- PHP engine alone: the PHP process, parsing, running, and formatting the cell. juphyter kernel minus PHP engine alone: ZeroMQ messaging, ipykernel, and the transport's socket hop. No-kernel rows: formatting in PHP.
- Cache
- Warm
- Memory metric
- Peak resident set size; PHP allocator peak. Peak resident set size: VmHWM of the PHP engine process from /proc/<pid>/status after the trivial cells; engine only, excluding the Python transport and Jupyter. PHP allocator peak: memory_get_peak_usage(true) in the engine after the trivial cells.
- Recorded
- 2026-11-01, commit 058bee5
Reproduction
bench/setup
bench/run cells
- Raw record
- site/benchmarks/cell-round-trip.json
- Source
- bench/cells.py
Not measured
No benchmark covers Quarto render time, which Quarto and Pandoc dominate, or a cell that streams large output.