osm-katana/bench_history.json
{"date":"2026-05-27","version":"0.1.2","engine":"baseline-vec-pool","machine":"Ryzen 9 7900","cores":12,"results":[{"name":"liechtenstein_osm_raw","converter":"osm2geoparquet","mode":"raw","input_mb":61.0,"time_s":0.18,"throughput_mbs":338.9,"peak_ram_mb":130},{"name":"liechtenstein_osm_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":61.0,"time_s":0.27,"throughput_mbs":225.9,"peak_ram_mb":189},{"name":"liechtenstein_bz2_raw","converter":"osm2geoparquet","mode":"raw","input_mb":5.3,"time_s":0.34,"throughput_mbs":15.6,"peak_ram_mb":292},{"name":"liechtenstein_bz2_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":5.3,"time_s":0.58,"throughput_mbs":9.1,"peak_ram_mb":496},{"name":"sweden_xml_to_pbf","converter":"xml2pbf","mode":"-","input_mb":14000.0,"time_s":10.6,"throughput_mbs":1320.8,"peak_ram_mb":null}]}
{"date":"2026-05-27","version":"0.1.2","engine":"baseline-vec-pool","machine":"Threadripper PRO 3975WX","cores":32,"results":[{"name":"planet_xml_to_pbf","converter":"xml2pbf","mode":"-","input_mb":147000.0,"time_s":1629.0,"throughput_mbs":90.2,"peak_ram_mb":null}]}
{"date":"2026-05-27","version":"0.1.2","engine":"gatling","machine":"unknown","cores":32,"results":[{"name":"liechtenstein_osm_raw","converter":"osm2geoparquet","mode":"raw","input_mb":60.12521266937256,"time_s":0.184756344,"throughput_mbs":325.42975990785226,"peak_ram_mb":null},{"name":"liechtenstein_osm_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":60.12521266937256,"time_s":0.350130129,"throughput_mbs":171.72247598655687,"peak_ram_mb":null},{"name":"liechtenstein_bz2_raw","converter":"osm2geoparquet","mode":"raw","input_mb":5.238345146179199,"time_s":0.349386287,"throughput_mbs":14.99299011177047,"peak_ram_mb":null},{"name":"liechtenstein_bz2_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":5.238345146179199,"time_s":0.578718036,"throughput_mbs":9.051636237891847,"peak_ram_mb":null},{"name":"liechtenstein_gz_raw","converter":"osm2geoparquet","mode":"raw","input_mb":6.397524833679199,"time_s":0.260692931,"throughput_mbs":24.540461489073515,"peak_ram_mb":null},{"name":"liechtenstein_gz_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":6.397524833679199,"time_s":0.440065657,"throughput_mbs":14.537659851241695,"peak_ram_mb":null},{"name":"liechtenstein_pbf_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":3.1971731185913086,"time_s":0.243799152,"throughput_mbs":13.113963245414851,"peak_ram_mb":null}]}
{"date":"2026-05-27","version":"0.1.2","engine":"gatling","machine":"unknown","cores":32,"results":[{"name":"liechtenstein_osm_raw","converter":"osm2geoparquet","mode":"raw","input_mb":60.12521266937256,"time_s":0.198362784,"throughput_mbs":303.1073241509484,"peak_ram_mb":null},{"name":"liechtenstein_osm_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":60.12521266937256,"time_s":0.346072518,"throughput_mbs":173.7358777196303,"peak_ram_mb":null},{"name":"liechtenstein_bz2_raw","converter":"osm2geoparquet","mode":"raw","input_mb":5.238345146179199,"time_s":0.346205052,"throughput_mbs":15.130758826070508,"peak_ram_mb":null},{"name":"liechtenstein_bz2_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":5.238345146179199,"time_s":0.59908861,"throughput_mbs":8.74385701670943,"peak_ram_mb":null},{"name":"liechtenstein_gz_raw","converter":"osm2geoparquet","mode":"raw","input_mb":6.397524833679199,"time_s":0.263924833,"throughput_mbs":24.239950295541906,"peak_ram_mb":null},{"name":"liechtenstein_gz_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":6.397524833679199,"time_s":0.437654591,"throughput_mbs":14.617748711515743,"peak_ram_mb":null},{"name":"liechtenstein_pbf_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":3.1971731185913086,"time_s":0.236600459,"throughput_mbs":13.512962451992996,"peak_ram_mb":null}]}
{"date":"2026-05-28","version":"0.1.3","engine":"gatling","machine":"unknown","cores":16,"results":[{"name":"liechtenstein_osm_to_pbf","converter":"xml2pbf","mode":"raw","input_mb":60.12521266937256,"time_s":0.149736531,"throughput_mbs":401.54004014806884,"peak_ram_mb":null},{"name":"liechtenstein_bz2_to_pbf","converter":"xml2pbf","mode":"raw","input_mb":5.238345146179199,"time_s":0.24889935,"throughput_mbs":21.046037871047872,"peak_ram_mb":null},{"name":"liechtenstein_osm_raw","converter":"osm2geoparquet","mode":"raw","input_mb":60.12521266937256,"time_s":0.1914438,"throughput_mbs":314.061947523882,"peak_ram_mb":null},{"name":"liechtenstein_osm_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":60.12521266937256,"time_s":0.335727264,"throughput_mbs":179.08945479439095,"peak_ram_mb":null},{"name":"liechtenstein_bz2_raw","converter":"osm2geoparquet","mode":"raw","input_mb":5.238345146179199,"time_s":0.31536241,"throughput_mbs":16.610556553582907,"peak_ram_mb":null},{"name":"liechtenstein_bz2_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":5.238345146179199,"time_s":0.575496283,"throughput_mbs":9.102309260578142,"peak_ram_mb":null},{"name":"liechtenstein_pbf_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":3.1971731185913086,"time_s":0.201850985,"throughput_mbs":15.839274297280781,"peak_ram_mb":null}]}
{"date":"2026-05-28","version":"0.1.3","git_hash":"5af2f48","engine":"gatling","machine":"T14s","cores":16,"results":[{"name":"liechtenstein_osm_to_pbf","converter":"xml2pbf","mode":"raw","input_mb":60.12521266937256,"time_s":0.074936193,"throughput_mbs":802.3521113405449,"peak_ram_mb":null},{"name":"liechtenstein_bz2_to_pbf","converter":"xml2pbf","mode":"raw","input_mb":5.238345146179199,"time_s":0.237473479,"throughput_mbs":22.058653320942838,"peak_ram_mb":null},{"name":"liechtenstein_osm_raw","converter":"osm2geoparquet","mode":"raw","input_mb":60.12521266937256,"time_s":0.212963643,"throughput_mbs":282.32618404904235,"peak_ram_mb":null},{"name":"liechtenstein_osm_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":60.12521266937256,"time_s":0.364332036,"throughput_mbs":165.02861875526244,"peak_ram_mb":null},{"name":"liechtenstein_bz2_raw","converter":"osm2geoparquet","mode":"raw","input_mb":5.238345146179199,"time_s":0.326747145,"throughput_mbs":16.0318008170483,"peak_ram_mb":null},{"name":"liechtenstein_bz2_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":5.238345146179199,"time_s":0.585552175,"throughput_mbs":8.945992124748233,"peak_ram_mb":null},{"name":"liechtenstein_pbf_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":3.1971731185913086,"time_s":0.190685499,"throughput_mbs":16.76673441534906,"peak_ram_mb":null}]}
{"date":"2026-05-28","version":"0.1.3","git_hash":"7354b35","engine":"gatling","machine":"T14s","cores":16,"results":[{"name":"liechtenstein_osm_to_pbf","converter":"xml2pbf","mode":"raw","input_mb":60.12521266937256,"time_s":0.090664639,"throughput_mbs":663.1605588742548,"peak_ram_mb":null},{"name":"liechtenstein_bz2_to_pbf","converter":"xml2pbf","mode":"raw","input_mb":5.238345146179199,"time_s":0.249092852,"throughput_mbs":21.02968874505961,"peak_ram_mb":null},{"name":"liechtenstein_osm_raw","converter":"osm2geoparquet","mode":"raw","input_mb":60.12521266937256,"time_s":0.206628798,"throughput_mbs":290.9817665849876,"peak_ram_mb":null},{"name":"liechtenstein_osm_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":60.12521266937256,"time_s":0.342552583,"throughput_mbs":175.52111895583795,"peak_ram_mb":null},{"name":"liechtenstein_bz2_raw","converter":"osm2geoparquet","mode":"raw","input_mb":5.238345146179199,"time_s":0.316038904,"throughput_mbs":16.57500098842008,"peak_ram_mb":null},{"name":"liechtenstein_bz2_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":5.238345146179199,"time_s":0.610453099,"throughput_mbs":8.581077161800433,"peak_ram_mb":null},{"name":"liechtenstein_pbf_resolved","converter":"osm2geoparquet","mode":"resolved","input_mb":3.1971731185913086,"time_s":0.179064146,"throughput_mbs":17.854903899026823,"peak_ram_mb":null}]}
{"date":"2026-06-17","version":"0.1.10","git_hash":"working-tree","engine":"gatling","machine":"Threadripper PRO 3975WX","cores":32,"note":"pass2 worker-side Arrow encode (collector now stitch-only) + core-aware psort SEQ_FLOOR + SlotFill::Big on PBF/XML/gz reads","results":[{"name":"sweden_pbf_resolved","converter":"convert","input_format":"pbf","mode":"resolved","input_mb":766.6,"time_s":7.62,"throughput_mbs":100.6,"cores_used":32,"phase_pass1_s":2.62,"phase_pass1_cores":16.3,"phase_sort_s":2.00,"phase_pass2_s":2.90,"phase_pass2_cores":18.3,"pass2_peak_cores_ge90":31,"nodes":104326671,"ways":9286473,"rels":274950},{"name":"sweden_pbf_resolved_BASELINE_pre_fix","converter":"convert","input_format":"pbf","mode":"resolved","input_mb":766.6,"time_s":18.92,"throughput_mbs":40.5,"cores_used":32,"phase_pass2_s":14.11,"phase_pass2_cores":3.46,"pass2_peak_cores_ge90":4,"note":"Incremental slots + fixed 2M SEQ_FLOOR + collector-side Arrow build (the regression)"}]}
{"date": "2026-06-18", "version": "0.1.10", "git_hash": "16db957", "engine": "gatling", "machine": "Threadripper PRO 3975WX", "cores": 32, "note": "PLANET path-matrix saturation proof (fix/osm-katana-gatling-saturation): streaming sort + coarse PBF split + ring slots. pass1/pass2 sustain ~28-31 of 32 cores at 162GB-planet scale (up from old ~11/~18 ceiling); sort_and_stree I/O-bound (~4-6 cores, expected). Run on /home, source bz2 read-only on /home copy. All outputs verified (geometry set, 0 null on nodes/ways).", "results": [{"name": "planet_bz2_to_pbf", "converter": "xml2pbf", "input_format": "bz2", "mode": "raw", "input_mb": 165112.0, "output_mb": 77781.0, "time_s": 900.0, "cores_used": 32, "cores_min": 28.9, "cores_avg": 30.3, "cores_max": 30.4, "note": "162GB planet bz2 -> 76GB zstd-blob pbf; external core-sampler (xml2pbf emits no phase telemetry). Sustained ~30/32 cores throughout."}, {"name": "planet_pbf_to_geo_chained", "converter": "convert", "input_format": "pbf", "mode": "resolved", "input_mb": 77781.0, "time_s": 600.1, "cores_used": 32, "phase_pass1_s": 197.12, "phase_pass1_cores_avg": 22.4, "phase_pass1_cores_max": 30.3, "phase_sort_s": 203.98, "phase_sort_cores_avg": 3.6, "phase_sort_cores_max": 6.1, "phase_pass2_s": 196.94, "phase_pass2_cores_avg": 27.8, "phase_pass2_cores_max": 30.2, "nodes": 10581367185, "ways": 1183237014, "rels": 14300803, "geo_bytes": 421000000000, "verify": "nodes 10581367185 (0 null), ways 1183237014 (1 null), rels 14300803"}, {"name": "planet_bz2_to_geo_direct", "converter": "convert", "input_format": "bz2", "mode": "resolved", "input_mb": 165112.0, "time_s": 1609.3, "cores_used": 32, "phase_pass1_s": 966.2, "phase_pass1_cores_avg": 30.3, "phase_pass1_cores_max": 30.8, "phase_sort_s": 193.91, "phase_sort_cores_avg": 3.8, "phase_sort_cores_max": 6.2, "phase_pass2_s": 447.38, "phase_pass2_cores_avg": 29.5, "phase_pass2_cores_max": 30.8, "nodes": 10581367185, "ways": 1183237014, "rels": 14300803, "geo_bytes": 337000000000, "verify": "nodes 10581367185 (0 null), ways 1183237014 (1 null), rels 14300803 \u2014 counts identical to chained path", "note": "one-shot bz2->geo (alternative to chained). pass1 includes full 162GB bz2 decode spread across all cores -> highest avg saturation (30.3)."}, {"name": "planet_geo_to_arrow", "converter": "geo2arrow", "input_format": "parquet", "mode": "ipc", "input_mb": 149833.0, "output_mb": 594228.0, "time_s": 760.0, "cores_used": 1, "rows": 10581367185, "arrow_batches": 10333367, "note": "serial parquet->Arrow IPC stream copy of planet nodes.parquet (10.58B rows). 1-core by design; 623GB uncompressed IPC. Deleted after to reclaim space."}, {"name": "europe_clip_convert", "converter": "convert", "input_format": "pbf", "mode": "resolved", "input_mb": 28340.0, "time_s": 208.4, "clip_s": 623.0, "cores_used": 32, "phase_pass1_s": 68.7, "phase_pass1_cores_avg": 23.0, "phase_pass1_cores_max": 29.1, "phase_sort_s": 64.86, "phase_sort_cores_avg": 3.5, "phase_sort_cores_max": 5.6, "phase_pass2_s": 74.43, "phase_pass2_cores_avg": 28.3, "phase_pass2_cores_max": 29.5, "nodes": 3187280625, "ways": 397672842, "rels": 6829350, "geo_bytes": 134000000000, "clip_source": "europe-latest.osm.pbf (geofabrik, 34GB zlib)", "clip_bbox": "-10,40,30,72", "clip_strategy": "complete_ways", "verify": "nodes 3187280625 (0 null), ways 397672842 (0 null), rels 6829350", "note": "\u00b1clip arm: osmium extract (970% CPU on zlib pbf, 623s) -> convert. pass2 sustains ~28-30 cores."}, {"name": "planet_bz2_osmium_clip_convert_ESTIMATE", "converter": "osmium+convert", "input_format": "bz2", "mode": "resolved", "input_mb": 165112.0, "time_s": 28800.0, "estimate": true, "cores_used": 1, "note": "ESTIMATE ~8h. osmium extract directly off the 162GB planet bz2 is single-threaded bz2 decode: measured 32.4/162 GB read in ~97 min (~20%) at ~160% CPU -> projected ~8h for the osmium step alone. NOT a regression in our convert (which saturates ~30 cores); bottleneck is libosmium's single-stream bzip2 reader. Aborted in favour of clipping the zlib europe pbf (europe_clip_convert above). Recorded per owner request."}]}
{"date": "2026-06-18", "version": "0.1.10", "git_hash": "working-tree", "engine": "gatling", "machine": "Threadripper PRO 3975WX", "cores": 32, "note": "region-clip (fix/osm-katana-gatling-saturation): clip Sweden's REAL polygon shape from a 32GB europe PBF via --poly sweden.poly (Geofabrik, 1 ring/146 verts). Per-node bbox+ray-cast at decode INSIDE the pass-1 workers (zero extra pass); pass-2 drops ways with zero in-region coords (node-membership). Output to /home, source read-only. vs osmium planet-bz2 clip ~8h single-threaded.", "results": [{"name": "sweden_polygon_clip_from_europe_pbf", "converter": "convert", "input_format": "pbf", "mode": "resolved", "clip": "sweden.poly (polygon, 146 verts)", "input_mb": 32715.0, "time_s": 65.0, "cores_used": 32, "avg_busy_cores": 29.9, "median_busy_cores": 31.9, "peak_busy_cores": 32.0, "phase_pass1_s": 20.6, "phase_pass1_cores": 28.7, "phase_sort_s": 1.2, "phase_pass2_s": 42.6, "phase_pass2_cores": 28.3, "nodes": 103482282, "ways": 9268029, "rels": 8320980, "ways_geom_null": 544, "reference_tool": "osmium extract --polygon (planet.osm.bz2)", "reference_time_s": 28800, "speedup_vs_osmium": "~440x walltime (different source: europe PBF vs planet bz2; clip stays Gatling at ~30/32 cores while osmium's bz2 clip is single-threaded)"}]}
{"date": "2026-08-02", "version": "0.2.0", "git_hash": "ed91395", "engine": "gatling", "machine": "oden \u2014 AMD Ryzen Threadripper PRO 3975WX", "cores": 32, "note": "BLOCK-PARALLEL bz2, before/after, and what an admin scan ADDS on top of it (feat/admin-poly-from-bz2-planet). Bencher: benches/bz2_block_parallel (harness=false, declared in Cargo.toml); wall time and cores-busy come from phase_log, the same channel `convert --log` writes. Inputs are named per row. BASELINE for context, phase-logged the same day from ~/.korp/work/*/convert.jsonl: three FULL two-pass converts of this planet ran 1866.3 s / 2056.3 s / 2117.7 s (31-35 min) at 29-30 of 32 cores \u2014 but a convert also builds a node store, resolves way node-refs, WKB-encodes and writes parquet, so it is not the same work. The comparable floor is the decompression, measured here directly. Contamination, stated: the planet admin-scan row ran while nice'd korp builds/tests shared the box; the decompression-floor row ran with only rust-analyzer (~1 core) alongside. A 1-worker arm on the 165 GiB planet was NOT run (~7 h by extrapolation) \u2014 the serial rate is measured on the 2 GiB slice instead.", "results": [{"name": "planet_bz2_decompress_only", "converter": "xml_scan::bz2_decode_probe", "input_format": "bz2", "input": "/home/rickard/work/planet-260427.osm.bz2", "input_mb": 165114.7, "time_s": 747.85, "workers": 31, "cores_used": 32, "cores_avg": 29.3, "busy_pct": 91.6, "in_mbs": 220.8, "decoded_mb": 2187891.4, "decoded_mbs": 2925.6, "note": "THE FLOOR under any single planet pass: every bz2 block decoded on a gatling worker and discarded, no parse, no payload. Span starts at the first data block (the changeset prologue is skipped), so it is the same span the admin scan's node pass covers."}, {"name": "planet_admin_poly_sweden", "converter": "admin-poly", "input_format": "bz2", "input": "/home/rickard/work/planet-260427.osm.bz2", "input_mb": 165114.7, "time_s": 1327.4, "workers": 31, "cores_used": 32, "phase_a_relations_s": 223.0, "phase_a_cores_avg": 29.55, "phase_b_ways_s": 229.42, "phase_b_cores_avg": 28.98, "phase_c_nodes_s": 874.95, "phase_c_cores_avg": 28.92, "relation": 52822, "admin_level": 2, "member_ways": 178, "boundary_nodes": 14600, "rings": 2, "vertices": 14602, "unclosed_chains": 0, "scan_overhead_vs_decompress_pct": 17.0, "note": "Sweden's boundary out of the planet. Pass C covers the same span as planet_bz2_decompress_only: 874.95 s vs 747.85 s, so VTD element parse + node-subset filter over 2.29 TB of decompressed XML costs +17.0 % on top of the decompression, i.e. decompression is 85.5 % of that pass. Passes A and B read only the file's way/relation tail (Bz2Skip::Nodes) and never touch the node section."}, {"name": "planet_slice_2g_bz2_decompress_scaling", "converter": "xml_scan::bz2_decode_probe", "input_format": "bz2", "input": "first 2 GiB of planet-260427.osm.bz2", "input_mb": 2048.0, "cores_used": 32, "single_core_mbs": 6.4, "multi_core_mbs": 63.7, "by_workers_s": {"1": 319.15, "2": 158.37, "4": 73.8, "8": 37.74, "16": 27.99, "31": 32.16}, "by_workers_mbs": {"1": 6.4, "2": 12.9, "4": 27.8, "8": 54.3, "16": 73.2, "31": 63.7}, "note": "Near-linear to 8 workers (8.46x); 16 gives 11.4x and 31 REGRESSES to 9.9x because 2 GiB is only ~10 of the engine's 200 MB slots, so ramp-up and drain dominate before the pipeline fills. The full planet does NOT have that ceiling: 220.8 MB/s at 31 workers, 34.5x this slice's 1-worker rate. Extrapolating 6.4 MB/s to the whole planet gives ~7.2 h serial, which matches the independently measured ~8 h osmium single-stream projection recorded 2026-06-18."}, {"name": "liechtenstein_bz2_admin_poly", "converter": "admin-poly", "input_format": "bz2", "input": "lbzip2/test_data/liechtenstein.osm.bz2", "input_mb": 5.2, "cores_used": 32, "by_workers_s": {"1": 3.34, "2": 2.6, "4": 2.21, "8": 2.16, "16": 2.06, "31": 2.0}, "decompress_by_workers_s": {"1": 0.77, "2": 0.51, "4": 0.27, "8": 0.19, "16": 0.22, "31": 0.18}, "note": "The default bench corpus \u2014 in-repo, seconds, no download. Too SMALL to show block parallelism (a handful of bz2 blocks; the three passes' fixed section-seek cost is most of the 2 s), so its 1.67x is a statement about the fixture, not about the engine. Kept because it is what a re-run on any machine can reproduce; the scaling number to quote is the 2 GiB slice."}]}
{"date": "2026-08-03", "version": "0.2.0", "git_hash": "working-tree", "engine": "gatling", "machine": "oden \u2014 AMD Ryzen Threadripper PRO 3975WX", "cores": 32, "note": "REGION CLIP COST, three approaches, same real corpus (benches/clip_containment). A clip is nodes x vertices; Sweden's real border (relation 52822) is 14 602 vertices where the downloaded outline it replaced had 146, so the question was whether full fidelity is affordable. Corpus: 52 931 795 REAL node coordinates sampled out of planet-260427.osm.bz2 at stride 200 (xml_scan::sample_node_coords, one 934.9 s node sweep, cached); 2.273 % of them land inside Sweden's bbox and pay for a ray-cast, and the kept count scales to 102 M against the 103.5 M a real Sweden clip produced, so the sample is representative. Planet figures below are ARITHMETIC on the measured per-node cost x 10 581 367 185 nodes / 31 workers \u2014 NOT a measured re-cut, which was deliberately not run. 'nodes_moved' counts corpus nodes given a different verdict than the full-fidelity exact ray-cast: it is the honest price of an approximation, and the whole reason the mask wins.", "results": [{"name": "sweden_clip_exact_raycast", "approach": "baseline (today)", "vertices": 14602, "ns_per_node": 264.6, "corpus_nodes": 52931795, "planet_clip_cpu_s": 2825, "planet_clip_wall_s": 91.1, "speedup_vs_today": 1.0, "nodes_moved": 0, "probes_wrong_of_43": 0, "note": "Per-node point-in-polygon inside the gatling pass-1 workers. ~91 s wall of a 1866-2118 s convert, i.e. ~5 % of it."}, {"name": "sweden_clip_gatling_fanout", "approach": "2 \u2014 parallelise the per-node test", "speedup_vs_today": 1.0, "nodes_moved": 0, "note": "NOTHING TO WIN \u2014 already done. clip_keeps runs inside the pass-1 workers (reader::read_pass1_mmap_planned -> par::par_map; xml_reader's bz2/XML pass-1 codecs call it in transform), measured at 29.9 avg / 31.9 median of 32 busy cores on a Sweden clip (2026-06-18 entry). Reported, not re-measured."}, {"name": "sweden_clip_mask_256", "approach": "3 \u2014 raster mask", "vertices": 14602, "ns_per_node": 7.4, "mask_bytes": 65536, "mask_build_ms": 4, "boundary_cells_pct": 2.35, "planet_clip_cpu_s": 78, "planet_clip_wall_s": 2.5, "speedup_vs_today": 36.2, "nodes_moved": 0}, {"name": "sweden_clip_mask_512", "approach": "3 \u2014 raster mask", "vertices": 14602, "ns_per_node": 5.9, "mask_bytes": 262144, "mask_build_ms": 2, "boundary_cells_pct": 1.18, "planet_clip_cpu_s": 62, "planet_clip_wall_s": 2.0, "speedup_vs_today": 45.7, "nodes_moved": 0}, {"name": "sweden_clip_mask_1024", "approach": "3 \u2014 raster mask (DEFAULT)", "vertices": 14602, "ns_per_node": 5.2, "mask_bytes": 1048576, "mask_build_ms": 2, "boundary_cells_pct": 0.6, "planet_clip_cpu_s": 54, "planet_clip_wall_s": 1.8, "speedup_vs_today": 52.0, "nodes_moved": 0, "probes_wrong_of_43": 0, "note": "The chosen default (Polygon::contains builds it above 512 vertices). Full 14 602-vertex fidelity at roughly what the 146-vertex DOWNLOADED outline would have cost. Scanline build (one even-odd sweep per grid row, gatling fork-join) is 2 ms, against 733 ms for korp-collectors' per-cell 192x192 coverage grid."}, {"name": "sweden_clip_mask_2048", "approach": "3 \u2014 raster mask", "vertices": 14602, "ns_per_node": 4.8, "mask_bytes": 4194304, "mask_build_ms": 3, "boundary_cells_pct": 0.3, "planet_clip_cpu_s": 51, "planet_clip_wall_s": 1.6, "speedup_vs_today": 55.5, "nodes_moved": 0, "note": "0.4 ns/node better than 1024\u00b2 for 4x the memory \u2014 not taken."}, {"name": "sweden_clip_simplified_eps0.0001", "approach": "1 \u2014 Douglas-Peucker", "vertices": 5899, "ns_per_node": 107.7, "planet_clip_wall_s": 36.8, "speedup_vs_today": 2.5, "nodes_moved": 41, "probes_wrong_of_43": 0, "area_err_pct": 0.0}, {"name": "sweden_clip_simplified_eps0.001", "approach": "1 \u2014 Douglas-Peucker", "vertices": 1543, "ns_per_node": 30.0, "planet_clip_wall_s": 10.3, "speedup_vs_today": 8.9, "nodes_moved": 92, "probes_wrong_of_43": 0, "area_err_pct": 0.003}, {"name": "sweden_clip_simplified_eps0.01", "approach": "1 \u2014 Douglas-Peucker", "vertices": 405, "ns_per_node": 9.3, "planet_clip_wall_s": 3.2, "speedup_vs_today": 28.7, "nodes_moved": 401, "probes_wrong_of_43": 0, "area_err_pct": 0.042, "note": "The best simplification that still passes all 43 named places \u2014 and it still moves 401 of 52.9 M corpus nodes (~80 k planet nodes) across the border."}, {"name": "sweden_clip_simplified_eps0.05", "approach": "1 \u2014 Douglas-Peucker", "vertices": 157, "ns_per_node": 4.7, "planet_clip_wall_s": 1.6, "speedup_vs_today": 57.3, "nodes_moved": 1883, "probes_wrong_of_43": 1, "area_err_pct": 0.119, "note": "RED: drops Treriksroset out of Sweden. Roughly Geofabrik's vertex count, and it shows what that resolution costs in geography."}, {"name": "sweden_clip_simplified_eps0.001_plus_mask", "approach": "1+3 composed", "vertices": 1543, "ns_per_node": 4.3, "planet_clip_wall_s": 1.5, "speedup_vs_today": 61.6, "nodes_moved": 92, "note": "Composing buys 0.9 ns/node over the mask alone and still moves 92 nodes: once the mask is in place only ~0.6 % of queries reach a ray-cast at all, so the vertex count has almost nothing left to pay for. Simplification is not worth its fidelity cost ON TOP of the mask."}]}
{"date": "2026-08-03", "version": "0.2.0", "git_hash": "measure/stree-as-clip-mask", "engine": "gatling", "machine": "oden \u2014 AMD Ryzen Threadripper PRO 3975WX", "cores": 32, "note": "CAN RAGNAR'S stree BE THE CLIP MASK? Ceiling measured FIRST, then the structure itself, on the cached 52 931 795-node real planet corpus (stride 200) against korp's sweden.poly (relation 52822, 14 602 vertices). CEILING: of the masked clip's 5.06 ns/node at 1024\u00b2, the boundary ray-cast \u2014 the ONLY term a sparse membership index can remove \u2014 is 0.86-1.06 ns (17-20 %, three runs). Only 3 890 of 52.9 M nodes (0.0073 %; 0.323 % of the 1 202 911 in-bbox) reach a ray-cast at all. A PERFECT index removing every one of them reaches 4.12 ns/node = 1.4 s of planet clip wall against 1.7 s today: ~0.3 s of a 1866-2118 s convert. CORRECTION to the 2026-08-02 entry's reading: the 63 % term is NOT the array index. It is what calling the mask adds over an inlined bbox compare across EVERY node (call + coordinate divisions + the loop no longer vectorising); the array index proper measures 2.3 ns per in-bbox query, ~0.05 ns/node amortised. Dense-vs-stree rows below use identical precomputed cell keys, results consumed (an unconsumed loop is deleted by the compiler and first reported a false 0.0 ns), and assert that both structures agree on which queries are boundary.", "results": [{"name": "clip_mask_1024_ceiling_decomposition", "corpus_nodes": 52931795, "ns_per_node_total": 5.06, "bbox_floor_ns": 0.98, "mask_call_all_nodes_ns": 3.14, "boundary_raycast_ns": 0.95, "boundary_raycast_share_pct": 18.7, "nodes_reaching_raycast": 3890, "raycast_us_each": 12.9, "perfect_index_ns_per_node": 4.12, "perfect_index_planet_wall_s": 1.4, "today_planet_wall_s": 1.7, "note": "The entire budget any sparse index competes for is 0.95 ns/node."}, {"name": "stree_vs_dense_1024", "grid": "1024\u00b2", "boundary_cells": 6256, "index_bytes": 50048, "dense_bytes": 1048576, "dense_build_ms": 2, "stree_build_ms": 0, "dense_ns_per_query": 2.3, "stree_scalar_ns_per_query": 37.1, "stree_batch_ns_per_query": 20.8, "boundary_query_pct": 0.323, "note": "batch_prefetch::<16> is the batch path. Dense direct addressing is 9.0x faster."}, {"name": "stree_vs_dense_4096", "grid": "4096\u00b2", "boundary_cells": 25320, "index_bytes": 202560, "dense_bytes": 16777216, "dense_build_ms": 14, "stree_build_ms": 0, "dense_ns_per_query": 5.1, "stree_scalar_ns_per_query": 36.7, "stree_batch_ns_per_query": 20.5, "boundary_query_pct": 0.094}, {"name": "stree_vs_dense_16384", "grid": "16384\u00b2", "boundary_cells": 101493, "index_bytes": 811944, "dense_bytes": 268435456, "dense_build_ms": 174, "stree_build_ms": 0, "dense_ns_per_query": 10.1, "stree_scalar_ns_per_query": 46.8, "stree_batch_ns_per_query": 24.8, "boundary_query_pct": 0.034, "note": "The sparse index's real advantage is MEMORY \u2014 0.77 MiB against a 256 MiB dense grid \u2014 not speed. Amortised over the corpus, stree at 16384\u00b2 lands at 4.81 ns/node against 5.06 today and 4.47 for the dense 16384\u00b2 grid: every arm inside 0.3 s of planet clip wall, i.e. inside the noise of a 1900 s convert."}]}