Benchmarks
sbt 'set core / Test / javaOptions += "-Dtui4s.stress=30"' 'core/testOnly tui4s.stress.PerfProbe'
This probe measures the pure layout and paint of one frame, with no runner and no terminal. It prints the median and the 90th percentile of each step, in ms, for a dashboard, a list of 2,000 rows and a log.
bench/
The bench/ directory compares the same apps in tui4s and in seven other terminal UI stacks (Java, Scala, Rust, Go, Python and Node.js). It has its own sbt build (bench/build.sbt) and its own CI job (bench). The headline is not speed. It is:
- Compactness: the size of the code of the same app.
- Expressiveness: what each library can say directly.
- Correctness: the same behaviour in each implementation.
- Resource management: how each library releases the terminal and its other resources.
A person of each ecosystem has not reviewed the implementations of the other stacks yet. The numbers of stage 1 come from a shared build container (4 vCPU, noisy). The run on a bounded cloud machine that stops by itself (bench/infra) is written, but it has not run yet.
Stage 1
Two tasks, a counter and a dashboard. "lines" is the source without blank lines and comments. "key-script steps" are the steps of the screen oracle of both tasks. "restore cases" are the six ways to end each task (quit, Ctrl-C, SIGTERM, SIGINT, a failure in a key handler, a kill during a frame) after which the terminal is restored. A mutant is a small bug in the counter (13 classes): "found" is the compiler, a crash or the oracle; "defused" has no effect; "silent" is wrong and passes; "not run" is not applicable or not written.
| Stack | Language | counter lines | dashboard lines | key-script steps | restore cases | mutants found | defused | silent | not run |
|---|---|---|---|---|---|---|---|---|---|
| tui4s | Scala | 27 | 78 | 28/28 | 12/12 | 8 | 2 | 2 | 1 |
| jatatui-plain | Java | 70 | 154 | 28/28 | 12/12 | 13 | 0 | 0 | 0 |
| TamboUI | Java | 46 | 120 | 28/28 | 10/12 | 11 | 0 | 1 | 1 |
| layoutz | Scala | 23 | 83 | 22/28 | 12/12 | 5 | 0 | 2 | 6 |
| ratatui | Rust | 53 | 138 | 28/28 | 12/12 | 12 | 0 | 1 | 0 |
| bubbletea | Go | 52 | 119 | 28/28 | 12/12 | 10 | 0 | 1 | 2 |
| Textual | Python | 37 | 102 | 28/28 | 12/12 | 6 | 2 | 1 | 4 |
| ink | Node.js | 28 | 103 | 28/28 | 12/12 | 8 | 0 | 1 | 4 |
layoutz never enters the alternate screen, and it fails the start, the modes and the resize steps. TamboUI shows an error screen after a failure in a key handler, and the next keys have no effect.
The full tables (tokens, gzip bytes, the concepts, the size of a change request, each restore case and each mutant) and the findings are in bench/README.md. The start time, the memory, the CPU and the size of each stack are on bench/PERFORMANCE.md, with the machine and the method.