Benchmarks
How fast is Dazzle compared with C++? Single constructs say little, because an indexed load compiles to the same instruction in both. These are whole programs instead. Each one is written idiomatically in both languages, built by the same compiler at the same optimisation level, and timed from start to finish.
- A* search: 200 searches across a 400×400 grid. It uses a generic binary heap, hash maps keyed by a struct, and allocation in every search.
- Tokenizer, parser and evaluator: 100,000 generated statements, about 8 MB of text. Each statement is parsed into a tree of tagged unions and evaluated, and about one in eight fails on purpose, through
!->. - Word count: 2,000,000 generated words. It counts every distinct word in a hash map, then sorts the counts.
Both halves of each pair print a checksum over their whole result, and a run whose two halves disagree is refused. Each C++ half is written as a C++ reviewer would accept it: std::vector, std::unordered_map, std::priority_queue, std::string, std::unique_ptr and std::sort. Each language uses its own standard library, as benchmarks between languages usually do, so a ratio includes each library’s design choices; the note below says where one decides it. The rules and sources are in the repository.
The latest run
Section titled “The latest run”A* search
Tokenizer, parser and evaluator
Word count
Dazzle C++. Shorter is better. The figure on the right is Dazzle's over C++'s: how many times as long, or as much memory; below 1.00× Dazzle is ahead. Run time is the median of 10 runs; peak memory is the largest resident set of any of them, the same with either compiler unless a row per compiler says otherwise.
AMD Ryzen 7 H 255 w/ Radeon 780M Graphics, Debian clang version 19.1.7 (3+b1) and g++ (Debian 14.2.0-19) 14.2.0, -O2 -flto=auto. Dazzle at f0a0ab9, 2026-11-04. Build times are below.
Build time
Section titled “Build time”Each half is built from clean three times, and the median is shown. For Dazzle, dz build --timings says where the time went, phase by phase: Dazzle’s own phases, from reading the manifests to emitting the C++; importing C and C++ headers with libclang; and the C++ compiler on the generated code. The C++ half is a single compiler invocation on one file.
A* search
Tokenizer, parser and evaluator
Word count
Dazzle's own phases C and C++ headers (libclang) C++ compiler, on the generated code other the C++ program, one compiler invocation. Median of 3 builds from clean.
| Phase | astar clang 19 | astar g++ 14 | expr clang 19 | expr g++ 14 | words clang 19 | words g++ 14 |
|---|---|---|---|---|---|---|
| manifests | 0.4 ms | 0.4 ms | 0.5 ms | 0.4 ms | 0.4 ms | 0.5 ms |
| C and C++ headers | 83.4 ms | 84.6 ms | 82.9 ms | 82.7 ms | 83.5 ms | 84.1 ms |
| lex and parse | 8.3 ms | 8.5 ms | 8.1 ms | 8.2 ms | 8.0 ms | 7.9 ms |
| #if and macros | 0.6 ms | 0.6 ms | 0.6 ms | 0.6 ms | 0.6 ms | 0.6 ms |
| resolve names | 1.1 ms | 1.0 ms | 1.0 ms | 1.0 ms | 1.0 ms | 1.0 ms |
| type check | 14.0 ms | 13.9 ms | 14.0 ms | 14.0 ms | 13.7 ms | 13.7 ms |
| ownership | 39.4 ms | 39.6 ms | 36.1 ms | 36.5 ms | 36.3 ms | 36.2 ms |
| placement | 9.6 ms | 9.5 ms | 7.8 ms | 7.8 ms | 8.2 ms | 8.3 ms |
| instantiate generics | 4.6 ms | 4.4 ms | 3.6 ms | 3.7 ms | 3.5 ms | 3.7 ms |
| emit C++ | 20.8 ms | 20.9 ms | 18.5 ms | 18.6 ms | 17.7 ms | 17.9 ms |
| C and C++ libraries | 0.1 ms | 0.1 ms | 0.1 ms | 0.1 ms | 0.1 ms | 0.1 ms |
| C++ compiler | 1838.7 ms | 1379.2 ms | 1923.0 ms | 1482.9 ms | 1807.5 ms | 1411.8 ms |
| total, wall clock | 2.03 s | 1.57 s | 2.11 s | 1.67 s | 1.99 s | 1.60 s |
Every run
Section titled “Every run”Each run is kept. As the compiler and the standard library improve, this is where the ratios should be seen to fall.
clang g++ — the geometric mean of the three programs' ratios, for each run. Lower is better; 1.0× is C++'s speed.
| Run | astar clang | astar g++ | expr clang | expr g++ | words clang | words g++ |
|---|---|---|---|---|---|---|
| f0a0ab9 2026-11-04, clang 19, g++ 14 Inlined index checks and Hash and Ord calls (T-0157), an introsort (T-0096), fewer moves through or return and a 24-byte Box (T-0097), parser nodes kept in their region (T-0146), short text kept inside a String (T-0156) and a SwissTable HashMap (T-0164). astar is faster than C++ and peaks under it, mostly because Dazzle's HashMap is a SwissTable where std::unordered_map allocates a node per entry; expr falls to 1.17x and 1.07x, words to 0.91x and 1.02x. | 0.77× | 0.88× | 1.17× | 1.07× | 0.91× | 1.02× |
| aa58e02 2026-11-03, clang 19, g++ 14 String::push_str copies in bulk and push writes ASCII directly (T-0155): words falls to 1.23x and 1.27x. astar on clang moved with code alignment; its own generated C++ is unchanged. | 1.19× | 1.12× | 2.10× | 1.66× | 1.23× | 1.27× |
| 4eaf644 2026-11-03, clang 19, g++ 14 Regions on by default, #[inline] and link-time optimisation (r104-r106). Same CPU as the first run, but Debian 13 with clang 19 and g++ 14 rather than CachyOS with clang 23 and g++ 16, so the two runs' ratios are not strictly comparable. | 1.13× | 1.10× | 2.06× | 1.66× | 1.48× | 1.39× |
| fdbd580 2026-10-25, clang 23, g++ 16 First whole-program benchmarks, with build phases. expr and words use Allocators::Temp. | 1.56× | 1.27× | 2.34× | 1.49× | 1.74× | 1.42× |
Run time: Dazzle's over C++'s.
| Run | astar clang | astar g++ | expr clang | expr g++ | words clang | words g++ |
|---|---|---|---|---|---|---|
| f0a0ab9 2026-11-04, clang 19, g++ 14 | 4.5× Dazzle 2.03 s C++ 452 ms own phases 99 ms | 4.1× Dazzle 1.57 s C++ 387 ms own phases 99 ms | 3.7× Dazzle 2.11 s C++ 569 ms own phases 90 ms | 3.3× Dazzle 1.67 s C++ 505 ms own phases 91 ms | 4.7× Dazzle 1.99 s C++ 425 ms own phases 89 ms | 3.8× Dazzle 1.60 s C++ 420 ms own phases 90 ms |
| aa58e02 2026-11-03, clang 19, g++ 14 | 4.5× Dazzle 2.02 s C++ 452 ms own phases 95 ms | 3.9× Dazzle 1.51 s C++ 389 ms own phases 94 ms | 4.1× Dazzle 2.33 s C++ 572 ms own phases 86 ms | 3.3× Dazzle 1.70 s C++ 510 ms own phases 87 ms | 4.8× Dazzle 2.02 s C++ 424 ms own phases 86 ms | 3.6× Dazzle 1.53 s C++ 421 ms own phases 85 ms |
| 4eaf644 2026-11-03, clang 19, g++ 14 | 4.5× Dazzle 2.02 s C++ 454 ms own phases 95 ms | 3.9× Dazzle 1.51 s C++ 387 ms own phases 94 ms | 4.1× Dazzle 2.35 s C++ 575 ms own phases 86 ms | 3.3× Dazzle 1.69 s C++ 508 ms own phases 87 ms | 4.7× Dazzle 2.00 s C++ 423 ms own phases 86 ms | 3.6× Dazzle 1.51 s C++ 419 ms own phases 85 ms |
| fdbd580 2026-10-25, clang 23, g++ 16 | 5.9× Dazzle 1.74 s C++ 296 ms own phases 38 ms | 7.3× Dazzle 2.55 s C++ 351 ms own phases 38 ms | 4.7× Dazzle 1.80 s C++ 379 ms own phases 36 ms | 6.2× Dazzle 2.87 s C++ 466 ms own phases 36 ms | 6.4× Dazzle 1.74 s C++ 272 ms own phases 34 ms | 6.4× Dazzle 2.52 s C++ 396 ms own phases 35 ms |
Build time from clean: Dazzle's over C++'s, with both times below it, and the part of Dazzle's spent in its own phases, from reading the manifests to emitting the C++.
Adding a run
Section titled “Adding a run”Run the suite on a quiet machine, from a Dazzle checkout at the commit being measured. Write its JSON into this site’s src/data/benchmarks/:
cargo build --release -p dzpython tools/bench_programs.py --json ../dazzle-lang.github.io/src/data/benchmarks/2026-11-30-abc1234.jsonThen add date, commit and a one-line summary at the top of the file. Runs are only comparable on the same machine and compilers, so a run on new hardware should say so in its summary.
