Skip to content

Commit 3dc8d7f

Browse files
authored
feat(benchmarks): add the DuckShop 10K generator (#1248)
1 parent 4e07586 commit 3dc8d7f

27 files changed

Lines changed: 8616 additions & 1 deletion

‎.github/workflows/verify.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ jobs:
163163
performance=true
164164
rules_performance=true
165165
;;
166-
src/sqlbuild/executor/testing/*|scripts/cold_compile_performance/*|scripts/compile_performance_ratio/*|scripts/compare_compile_performance.py|tests/e2e/src/sqlbuild/cli/commands/main/compile/*)
166+
benchmarks/duckshop-10k/*|src/sqlbuild/executor/testing/*|scripts/cold_compile_performance/*|scripts/compile_performance_ratio/*|scripts/compare_compile_performance.py|tests/e2e/src/sqlbuild/cli/commands/main/compile/*)
167167
broad=true
168168
performance=true
169169
;;

‎Makefile‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,14 @@ test-e2e-dense-compile-performance:
299299
-n auto --dist loadfile \
300300
-m cold_compile_performance -k "models_$(SQLBUILD_BENCHMARK_MODELS)_" \
301301
-vv -rP --log-level=INFO --log-cli-level=INFO --color=yes
302+
# DuckShop 10K runs after the dense guards, alone, so it never shares the memory limit with them.
303+
if [ "$(SQLBUILD_BENCHMARK_MODELS)" = "10000" ]; then \
304+
env PYTHONUNBUFFERED=1 uv run pytest benchmarks/duckshop-10k/tests -q --color=yes && \
305+
env PYTHONUNBUFFERED=1 SQLBUILD_CONCURRENCY=4 uv run pytest \
306+
tests/e2e/src/sqlbuild/cli/commands/main/compile/test_duckshop_10k_compile.py \
307+
-m cold_compile_performance -k "models_$(SQLBUILD_BENCHMARK_MODELS)_" \
308+
-vv -rP --log-level=INFO --log-cli-level=INFO --color=yes; \
309+
fi
302310

303311
test-e2e-cache-compile-performance:
304312
test -n "$(SQLBUILD_BENCHMARK_MODELS)"

‎benchmarks/duckshop-10k/README.md‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# DuckShop 10K
2+
3+
A deterministic generator for a ten-thousand-model SQLBuild project in Snowflake SQL. It describes
4+
Mallard & Co., the fictional duck-themed home goods business of the
5+
[DuckShop](../duckshop/README.md) project, after a decade of growth: 40 storefronts in 10 regions,
6+
marketplace partners, carriers, warehouses, retail stores, suppliers, payment gateways, ad
7+
networks, messaging, affiliates, support tools, ledgers, wholesale desks, returns portals and a
8+
product catalogue. Every name and value is invented.
9+
10+
Only the generator, its tests and `checksum.txt` are committed. The generated project is written
11+
to a directory you choose.
12+
13+
## Usage
14+
15+
```bash
16+
python benchmarks/duckshop-10k/generate.py --out /path/to/duckshop-10k # write the project
17+
python benchmarks/duckshop-10k/generate.py --verify /path/to/duckshop-10k # check a written copy
18+
python benchmarks/duckshop-10k/generate.py --check # check an in-memory build
19+
cd /path/to/duckshop-10k && sqb compile # no warehouse connection needed
20+
```
21+
22+
`--profile smoke` writes a small project of about 1,100 models with the same templates, for fast
23+
iteration. `checksum.txt` records the full profile only.
24+
25+
## Determinism and versioning
26+
27+
The generator uses no randomness, clocks or environment: the same generator version always writes
28+
byte-identical files. `checksum.txt` holds the generator version, the file count and the SHA-256 of
29+
`MANIFEST.sha256`, a sorted list of the SHA-256 of every generated file.
30+
31+
When a change alters any generated file, bump `GENERATOR_VERSION` in `duckshop10k/__init__.py` and
32+
run `python benchmarks/duckshop-10k/generate.py --update-checksum`.
33+
34+
## Shape
35+
36+
| | Count |
37+
|---|---|
38+
| Models | 10,282 |
39+
| Staging, intermediate, marts and snapshots | 6,149 (59.8%), 1,961 (19.1%), 2,162 (21.0%), 10 |
40+
| Sources | 2,466 table sources and one expression source |
41+
| Unit tests and scenarios | 288 and 2 |
42+
| Dependency depth | 11 at most; 168 models at depth 7 or more |
43+
44+
Most models read one to four upstreams; a few dozen wide marts, unions and scorecards read ten or
45+
more. Staging deduplicates change logs with a change-log macro, types three platform layouts
46+
(legacy columns with local times, typed columns with offset times, and JSON documents with epoch
47+
times) and flattens arrays into child models. The intermediate layer converts every instance to a
48+
shared shape (UTC times, major-unit amounts, mapped statuses), enriches headers with child totals,
49+
unions instances by region and company, converts currencies with `ASOF JOIN`, sessionises
50+
clickstream events in microbatches and builds customer identity, value and segment models and a
51+
budget variance chain. Marts give every instance, team and region its reports, and publish facts and
52+
dimensions with enforced contracts.
53+
54+
The models that use `HASH`, `TIMESTAMP_LTZ` or `CURRENT_TIMESTAMP()` are tagged `known_divergence`,
55+
because their results depend on the engine or the session.
56+
57+
## Checks
58+
59+
- `benchmarks/duckshop-10k/tests/` checks the shape, the determinism of two builds, the recorded
60+
checksum and the generated custom Rule's tests, offline.
61+
- `tests/e2e/.../compile/test_duckshop_10k_compile.py` generates the project, verifies it against
62+
`checksum.txt` and compiles it cold with the checkout's build, requiring zero errors and zero
63+
warnings.
64+
65+
CI runs both in the 10,000-model cell of the dense compile job, under its 4 GiB memory limit, after
66+
the dense guards have finished, so the DuckShop compile never shares the limit with them.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
generator 1 files 10874 sha256 4d276ad2428841efa2a1b851c83863bea70505d9e085a71390401399b5667667
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"""Deterministic generator for DuckShop 10K, a ten-thousand-model SQLBuild project.
2+
3+
The same generator version always writes byte-identical output. Bump GENERATOR_VERSION, and
4+
regenerate checksum.txt, whenever a change alters any generated file.
5+
"""
6+
7+
GENERATOR_VERSION = "1"
8+
SEED = 20261024
9+
PROJECT_NAME = "duckshop_10k"

0 commit comments

Comments
 (0)