Skip to content

Commit 39296e3

Browse files
revamped ops bench for better cost tuning
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 3b3a3c9 commit 39296e3

3 files changed

Lines changed: 286 additions & 180 deletions

File tree

bench/ops/README.md

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,64 @@
11
# Ops Calibration Benchmark
22

3-
Measures warm probe time per `(index_kind, query_kind)` at multiple N values and derives
4-
the `per_ns` constants used in `CostFactors` (`src/planner/calibration.rs`).
3+
Measures the 9 `CostFactors` ns/op constants used by the query planner's cost model
4+
(`src/planner/cost.rs`, `src/planner/calibration.rs`).
55

6-
## What it measures
7-
8-
| Constant | Index | Query kind | Dataset |
9-
|----------|-------|------------|---------|
10-
| `kdtree_knn_ns` | KDTree | kNN | clustered points |
11-
| `kdtree_range_ns` | KDTree | range | clustered points |
12-
| `rtree_knn_ns` | RTree | kNN | polygons |
13-
| `rtree_range_ns` | RTree | range | polygons |
14-
| `grid_range_ns` | Grid | range | uniform points |
15-
| `scan_ns_per_item` | BruteForce | kNN | uniform points |
16-
| `build_ns_per_item` | KDTree || clustered points |
17-
18-
Brute-force scan is only measured up to `--brute-max-n` (default 100,000) since it grows
19-
as `Q×N` and becomes impractical at large N.
6+
## Method
207

21-
All data is generated over `[0, 1]²`. Range queries use a `0.1 × 0.1` bbox (selectivity ≈ 0.01).
22-
kNN uses k=5. Each timing is the median of `--runs` repetitions.
8+
- Each dataset size generates synthetic data with numpy (uniform or clustered points) or
9+
`shapely.box` (polygons), then wraps it in a `SpatialFrame`/`Engine`.
10+
- Build cost times only `engine.build_index()` on a fresh engine. Probe cost times the repeated queries against a pre-built index.
11+
- The constant is `time / workload_term`, where the term is read directly off the cost
12+
model formula in `cost.rs` (e.g. `Q * N` for `scan_ns_per_item`).
13+
- This ratio is computed at multiple dataset sizes and we return the median as the suggested value.
2314

24-
## How constants are derived
2515

26-
Each measured warm time `T` (ms) is inverted through the cost model formula:
16+
## What it measures
2717

28-
| Constant | Formula |
29-
|----------|---------|
30-
| `kd_knn_ns`, `rt_knn_ns` | `T × 1e6 / (Q × (log₂N + k))` |
31-
| `kd_range_ns`, `rt_range_ns` | `T × 1e6 / (Q × (log₂N + sel×N))` |
32-
| `grid_range_ns` | `T × 1e6 / (Q × sel×N)` |
33-
| `scan_ns_per_item` | `T × 1e6 / (Q × N)` |
34-
| `build_ns_per_item` | `T × 1e6 / (N × log₂N)` |
18+
| Constant | Op timed | Dataset | Term |
19+
|---|---|---|---|
20+
| `scan_ns_per_item` | brute-force kNN, no index | uniform points | `Q * N` |
21+
| `grid_build_ns_per_item` | build | uniform points | `N` |
22+
| `kdtree_build_ns_per_item` | build | clustered points | `N * log2(N)` |
23+
| `rtree_build_ns_per_item` | build | polygons | `N * log2(N)` |
24+
| `grid_range_ns` | range probe | uniform points | true hit total |
25+
| `kdtree_range_ns` | range probe | clustered points | `Q * log2(N)` + true hit total |
26+
| `rtree_range_ns` | range probe | polygons | `Q * log2(N)` + true hit total |
27+
| `kdtree_knn_ns` | kNN probe | clustered points | `Q * (log2(N) + k)` |
28+
| `rtree_knn_ns` | kNN probe | polygons | `Q * (log2(N) + k)` |
3529

3630
## Running
3731

3832
```
3933
uv run python -m bench.ops
4034
```
4135

42-
Optional flags:
36+
Flags:
4337

4438
```
45-
--sizes N [N ...] dataset sizes to sweep (default: 10000 100000 500000 1000000)
46-
--queries Q queries per timing call (default: 500)
47-
--runs R repetitions per measurement, median taken (default: 3)
48-
--brute-max-n N skip brute-force above this N (default: 100000)
39+
--runs R timing repetitions per measurement, the minimum is taken (default: 3)
40+
--seed S RNG seed for data and query generation (default: 42)
4941
```
42+
43+
## Example Output
44+
45+
```
46+
Suggested CostFactors (copy into src/planner/calibration.rs):
47+
48+
Brute Force
49+
scan_ns_per_item: 100.80,
50+
51+
Points
52+
grid_build_ns_per_item: 84.74,
53+
kdtree_build_ns_per_item: 4.36,
54+
grid_range_ns: 211.38,
55+
kdtree_range_ns: 81.19,
56+
kdtree_knn_ns: 148.71,
57+
58+
Polygons
59+
rtree_build_ns_per_item: 74.17,
60+
rtree_range_ns: 176.16,
61+
rtree_knn_ns: 1299.75,
62+
63+
elapsed: 20.3 s peak RSS: 268.9 MiB
64+
```

0 commit comments

Comments
 (0)