Skip to content

Commit c161a83

Browse files
authored
Merge pull request #2899 from GaijinEntertainment/bbatkin/linq-fold-emission-lanes-pr4
linq_fold: Phase F PR 4 — FoldArray lane + migrate 5 fns
2 parents c0ce6ad + 56985e7 commit c161a83

4 files changed

Lines changed: 383 additions & 341 deletions

File tree

benchmarks/sql/results.md

Lines changed: 101 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Benchmarks — SQL / Array / Decs comparison
22

3-
Generated 2026-05-26 from `e968eec74` (PR F3 R1 — Copilot follow-up). Matrix refreshed for **Phase F PRs F1+F2+F3** (Terminator lane unification — `TerminatorSpec` for array side + `DecsTerminatorSpec` + `DecsDispatch` for decs side; 9 emit fns migrated to spec-builders). All three PRs verified AST byte-identical at emit time, so the cross-the-board 15-30% drop vs the prior `0f88a64b6` (PR D3) baseline reflects environment delta + cumulative wins across PR E + F1-F3, not refactor-introduced perf change. No regressions in any cell.
3+
Generated 2026-05-27 from `a063a0605` (PR F4 — FoldArray lane). Matrix refreshed for **Phase F PR F4** (FoldArray lane unification — `FoldArraySpec` + `DistinctGateSpec` + `emit_fold_array_lane` + `build_terminal_select_tail`; 5 emit fns migrated). All cells within 5% of the F3 baseline (`e968eec74`); apparent regressions in 2 cells (distinct_by_count m3f / sort_take_select m4) verified as bench-suite ordering noise (isolated re-runs match baseline).
44
Fixture size: n = 100 000 (cars), 100 dealers, 5 brands. Each row is
55
one bench family in `benchmarks/sql/`; columns are nanoseconds per
66
logical operation. `` marks an intentionally absent lane — see
@@ -22,150 +22,151 @@ Sub-nanosecond cells (`0.00`) reflect early-exit terminators that exit
2222
before the timer resolution can measure them — they should be read as
2323
"effectively free."
2424

25+
2526
## INTERP
2627

2728
| Benchmark | SQL (m1) | Array (m3f) | Decs (m4) | Decs vs Array |
2829
|---|---:|---:|---:|---:|
29-
| `aggregate_match` | 34.5 | 6.0 | 5.9 | 0.98× |
30-
| `all_match` | 27.7 | 3.5 | 3.6 | 1.03× |
30+
| `aggregate_match` | 34.7 | 6.0 | 5.9 | 0.98× |
31+
| `all_match` | 27.8 | 3.6 | 3.5 | 0.97× |
3132
| `any_match` | 0.00 | 0.00 | 0.00 ||
32-
| `average_aggregate` | 29.9 | 6.0 | 8.8 | 1.47× |
33-
| `bare_order_where` | 273.9 | 117.7 | 124.1 | 1.05× |
34-
| `chained_select_collapse` || 17.9 | 17.6 | 0.98× |
35-
| `chained_where` | 36.2 | 6.7 | 7.2 | 1.07× |
33+
| `average_aggregate` | 30.3 | 5.9 | 8.7 | 1.47× |
34+
| `bare_order_where` | 277.4 | 117.2 | 124.6 | 1.06× |
35+
| `chained_select_collapse` || 17.8 | 18.3 | 1.03× |
36+
| `chained_where` | 36.9 | 6.7 | 7.1 | 1.06× |
3637
| `contains_match` | 0.00 | 2.2 | 1.4 | 0.64× |
37-
| `count_aggregate` | 29.3 | 4.1 | 4.1 | 1.00× |
38+
| `count_aggregate` | 29.5 | 4.2 | 4.1 | 0.98× |
3839
| `decs_count_bare_pred` ||| 4.2 ||
39-
| `distinct_by_count` | 41.1 | 15.8 | 16.0 | 1.01× |
40-
| `distinct_by_order_take` || 21.8 | 23.3 | 1.07× |
41-
| `distinct_count` | 42.1 | 16.2 | 16.1 | 0.99× |
42-
| `distinct_count_pred` || 15.8 | 16.1 | 1.02× |
40+
| `distinct_by_count` | 41.2 | 15.8 | 15.7 | 0.99× |
41+
| `distinct_by_order_take` || 21.9 | 23.4 | 1.07× |
42+
| `distinct_count` | 41.7 | 16.1 | 15.9 | 0.99× |
43+
| `distinct_count_pred` || 15.9 | 16.1 | 1.01× |
4344
| `distinct_take` | 0.00 | 0.00 | 0.00 ||
4445
| `element_at_match` | 0.00 | 0.00 | 0.00 ||
4546
| `first_match` | 0.00 | 0.00 | 0.00 ||
4647
| `first_or_default_match` | 0.00 | 0.00 | 0.00 ||
47-
| `groupby_average` | 172.7 | 30.8 | 30.3 | 0.98× |
48-
| `groupby_count` | 141.6 | 19.5 | 19.3 | 0.99× |
49-
| `groupby_first` || 18.6 | 19.2 | 1.03× |
50-
| `groupby_having_count` | 142.9 | 19.4 | 19.3 | 0.99× |
51-
| `groupby_having_hidden_sum` | 175.1 | 24.0 | 24.3 | 1.01× |
52-
| `groupby_having_post_where` | 173.0 | 18.6 | 18.8 | 1.01× |
53-
| `groupby_max` | 173.4 | 25.2 | 25.2 | 1.00× |
54-
| `groupby_min` | 174.3 | 25.1 | 25.3 | 1.01× |
55-
| `groupby_multi_reducer` | 192.6 | 32.7 | 32.6 | 1.00× |
56-
| `groupby_select_order` | 171.3 | 18.7 | 18.9 | 1.01× |
57-
| `groupby_select_sum` | 205.0 | 36.8 | 36.0 | 0.98× |
58-
| `groupby_sum` | 173.6 | 18.8 | 18.6 | 0.99× |
59-
| `groupby_where_count` | 75.5 | 14.6 | 15.1 | 1.03× |
60-
| `groupby_where_sum` | 87.1 | 14.3 | 14.7 | 1.03× |
61-
| `indexed_lookup` | 1462.1 | 205000.2 | 475.5 | 0.00× |
62-
| `join_count` | 38.1 | 121.7 | 64.3 | 0.53× |
63-
| `join_groupby_count` || 187.4 | 91.5 | 0.49× |
64-
| `join_groupby_to_array` || 216.5 | 90.7 | 0.42× |
65-
| `join_select` || 150.8 | 85.8 | 0.57× |
66-
| `join_where_count` | 39.9 | 148.6 | 75.0 | 0.50× |
67-
| `last_match` | 0.00 | 5.9 | 14.0 | 2.37× |
68-
| `long_count_aggregate` | 29.4 | 4.1 | 4.1 | 1.00× |
69-
| `max_aggregate` | 30.5 | 6.0 | 6.9 | 1.15× |
70-
| `min_aggregate` | 30.5 | 6.1 | 6.8 | 1.11× |
71-
| `order_distinct_take` || 15.9 |||
72-
| `order_reverse_normalized` | 38.1 | 16.2 | 20.1 | 1.24× |
73-
| `order_take_desc` | 38.3 | 16.2 | 19.9 | 1.23× |
74-
| `reverse_take` | 0.10 | 0.00 | 10.2 ||
75-
| `reverse_take_select` | 0.00 | 34.0 | 48.6 | 1.43× |
48+
| `groupby_average` | 172.6 | 30.0 | 30.2 | 1.01× |
49+
| `groupby_count` | 142.8 | 19.4 | 19.5 | 1.01× |
50+
| `groupby_first` || 18.5 | 19.2 | 1.04× |
51+
| `groupby_having_count` | 142.6 | 19.2 | 19.2 | 1.00× |
52+
| `groupby_having_hidden_sum` | 175.9 | 23.9 | 24.5 | 1.03× |
53+
| `groupby_having_post_where` | 171.1 | 18.5 | 18.8 | 1.02× |
54+
| `groupby_max` | 173.7 | 25.1 | 25.2 | 1.00× |
55+
| `groupby_min` | 175.1 | 25.9 | 25.1 | 0.97× |
56+
| `groupby_multi_reducer` | 191.2 | 32.1 | 32.5 | 1.01× |
57+
| `groupby_select_order` | 171.3 | 18.6 | 18.7 | 1.01× |
58+
| `groupby_select_sum` | 198.9 | 36.8 | 36.1 | 0.98× |
59+
| `groupby_sum` | 173.6 | 18.7 | 18.5 | 0.99× |
60+
| `groupby_where_count` | 75.5 | 14.5 | 14.9 | 1.03× |
61+
| `groupby_where_sum` | 86.8 | 14.3 | 14.5 | 1.01× |
62+
| `indexed_lookup` | 1441.0 | 203842.2 | 471.7 | 0.00× |
63+
| `join_count` | 38.5 | 120.8 | 66.9 | 0.55× |
64+
| `join_groupby_count` || 187.3 | 90.6 | 0.48× |
65+
| `join_groupby_to_array` || 219.1 | 90.6 | 0.41× |
66+
| `join_select` || 148.0 | 84.9 | 0.57× |
67+
| `join_where_count` | 39.4 | 152.8 | 74.1 | 0.48× |
68+
| `last_match` | 0.00 | 6.0 | 14.0 | 2.33× |
69+
| `long_count_aggregate` | 29.8 | 4.2 | 4.1 | 0.98× |
70+
| `max_aggregate` | 31.2 | 6.0 | 6.9 | 1.15× |
71+
| `min_aggregate` | 31.1 | 6.1 | 6.9 | 1.13× |
72+
| `order_distinct_take` || 16.0 |||
73+
| `order_reverse_normalized` | 38.4 | 16.0 | 19.9 | 1.24× |
74+
| `order_take_desc` | 38.7 | 16.1 | 20.1 | 1.25× |
75+
| `reverse_take` | 0.10 | 0.00 | 10.1 ||
76+
| `reverse_take_select` | 0.00 | 33.8 | 48.1 | 1.42× |
7677
| `select_count` | 0.10 | 0.00 | 2.2 ||
77-
| `select_where` | 192.5 | 11.4 | 19.5 | 1.71× |
78-
| `select_where_count` | 32.4 | 5.2 | 7.4 | 1.42× |
79-
| `select_where_order_take` | 36.4 | 12.4 | 14.9 | 1.20× |
80-
| `select_where_sum` | 37.0 | 7.5 | 7.5 | 1.00× |
81-
| `single_match` | 0.00 | 3.0 | 5.5 | 1.83× |
78+
| `select_where` | 194.2 | 11.1 | 19.7 | 1.77× |
79+
| `select_where_count` | 35.2 | 5.2 | 7.8 | 1.50× |
80+
| `select_where_order_take` | 38.4 | 12.3 | 15.0 | 1.22× |
81+
| `select_where_sum` | 37.6 | 7.5 | 7.5 | 1.00× |
82+
| `single_match` | 0.00 | 2.9 | 5.6 | 1.93× |
8283
| `skip_take` | 0.50 | 0.10 | 0.20 | 2.00× |
83-
| `skip_while_match` | 3.5 | 5.3 | 5.3 | 1.00× |
84-
| `sort_first` | 38.5 | 11.1 | 13.3 | 1.20× |
85-
| `sort_take` | 38.0 | 16.4 | 20.9 | 1.27× |
86-
| `sort_take_select` | 38.1 | 16.2 | 20.4 | 1.26× |
87-
| `sum_aggregate` | 29.9 | 2.2 | 2.1 | 0.95× |
88-
| `sum_where` | 32.8 | 4.3 | 4.3 | 1.00× |
84+
| `skip_while_match` | 3.5 | 5.2 | 5.3 | 1.02× |
85+
| `sort_first` | 38.2 | 11.0 | 13.5 | 1.23× |
86+
| `sort_take` | 38.5 | 16.4 | 20.7 | 1.26× |
87+
| `sort_take_select` | 38.7 | 16.1 | 20.1 | 1.25× |
88+
| `sum_aggregate` | 30.1 | 2.2 | 2.1 | 0.95× |
89+
| `sum_where` | 33.0 | 4.3 | 4.3 | 1.00× |
8990
| `take_count` | 3.6 | 0.20 | 0.40 | 2.00× |
9091
| `take_count_filtered` || 0.20 | 0.20 | 1.00× |
9192
| `take_sum_aggregate` || 0.10 | 0.10 | 1.00× |
92-
| `take_where_count` || 0.10 | 35.4 | 354.00× |
93-
| `take_while_match` | 7.8 | 2.4 | 2.5 | 1.04× |
94-
| `to_array_filter` | 71.0 | 11.8 | 11.9 | 1.01× |
95-
| `zip_count_pred` || 15.1 |||
96-
| `zip_dot_product` || 12.8 | 10.7 | 0.84× |
97-
| `zip_dot_product_3arg` || 12.8 |||
93+
| `take_where_count` || 0.10 | 35.1 | 351.00× |
94+
| `take_while_match` | 7.8 | 2.4 | 2.4 | 1.00× |
95+
| `to_array_filter` | 70.6 | 11.7 | 11.8 | 1.01× |
96+
| `zip_count_pred` || 15.2 |||
97+
| `zip_dot_product` || 12.6 | 10.7 | 0.85× |
98+
| `zip_dot_product_3arg` || 12.7 |||
9899

99100
## JIT
100101

101102
| Benchmark | SQL (m1) | Array (m3f) | Decs (m4) | Decs vs Array |
102103
|---|---:|---:|---:|---:|
103-
| `aggregate_match` | 34.8 | 0.40 | 0.70 | 1.75× |
104-
| `all_match` | 27.8 | 0.30 | 0.20 | 0.67× |
104+
| `aggregate_match` | 34.6 | 0.40 | 0.70 | 1.75× |
105+
| `all_match` | 27.6 | 0.30 | 0.20 | 0.67× |
105106
| `any_match` | 0.00 | 0.00 | 0.00 ||
106107
| `average_aggregate` | 29.9 | 1.0 | 3.6 | 3.60× |
107-
| `bare_order_where` | 183.8 | 34.0 | 35.0 | 1.03× |
108+
| `bare_order_where` | 182.5 | 33.9 | 34.6 | 1.02× |
108109
| `chained_select_collapse` || 2.1 | 2.1 | 1.00× |
109-
| `chained_where` | 36.4 | 0.60 | 0.90 | 1.50× |
110+
| `chained_where` | 36.2 | 0.60 | 0.90 | 1.50× |
110111
| `contains_match` | 0.00 | 0.20 | 0.10 | 0.50× |
111-
| `count_aggregate` | 29.4 | 0.40 | 0.60 | 1.50× |
112+
| `count_aggregate` | 29.3 | 0.40 | 0.60 | 1.50× |
112113
| `decs_count_bare_pred` ||| 0.60 ||
113-
| `distinct_by_count` | 41.3 | 2.1 | 2.1 | 1.00× |
114-
| `distinct_by_order_take` || 2.7 | 3.2 | 1.19× |
115-
| `distinct_count` | 41.2 | 2.1 | 2.1 | 1.00× |
114+
| `distinct_by_count` | 40.8 | 2.7 | 2.1 | 0.78× |
115+
| `distinct_by_order_take` || 2.6 | 3.2 | 1.23× |
116+
| `distinct_count` | 41.5 | 2.1 | 2.1 | 1.00× |
116117
| `distinct_count_pred` || 2.1 | 2.3 | 1.10× |
117118
| `distinct_take` | 0.00 | 0.00 | 0.00 ||
118119
| `element_at_match` | 0.00 | 0.00 | 0.00 ||
119120
| `first_match` | 0.00 | 0.00 | 0.00 ||
120121
| `first_or_default_match` | 0.00 | 0.00 | 0.00 ||
121-
| `groupby_average` | 173.1 | 2.6 | 2.9 | 1.12× |
122-
| `groupby_count` | 141.3 | 2.4 | 2.5 | 1.04× |
122+
| `groupby_average` | 171.0 | 2.6 | 2.9 | 1.12× |
123+
| `groupby_count` | 143.9 | 2.4 | 2.5 | 1.04× |
123124
| `groupby_first` || 2.2 | 3.1 | 1.41× |
124-
| `groupby_having_count` | 141.8 | 2.4 | 2.5 | 1.04× |
125-
| `groupby_having_hidden_sum` | 179.5 | 2.5 | 2.8 | 1.12× |
126-
| `groupby_having_post_where` | 172.8 | 2.4 | 2.7 | 1.13× |
127-
| `groupby_max` | 173.7 | 2.4 | 2.7 | 1.13× |
128-
| `groupby_min` | 173.8 | 2.4 | 2.7 | 1.13× |
129-
| `groupby_multi_reducer` | 190.7 | 2.7 | 3.0 | 1.11× |
130-
| `groupby_select_order` | 171.5 | 2.4 | 2.7 | 1.13× |
131-
| `groupby_select_sum` | 204.0 | 3.2 | 3.7 | 1.16× |
132-
| `groupby_sum` | 172.2 | 2.4 | 2.7 | 1.13× |
133-
| `groupby_where_count` | 75.7 | 1.5 | 1.8 | 1.20× |
134-
| `groupby_where_sum` | 87.0 | 1.5 | 1.8 | 1.20× |
135-
| `indexed_lookup` | 1242.9 | 35154.5 | 106.4 | 0.00× |
136-
| `join_count` | 38.1 | 34.6 | 12.9 | 0.37× |
137-
| `join_groupby_count` || 47.4 | 22.0 | 0.46× |
138-
| `join_groupby_to_array` || 54.6 | 21.9 | 0.40× |
139-
| `join_select` || 41.6 | 22.6 | 0.54× |
140-
| `join_where_count` | 39.4 | 41.3 | 23.2 | 0.56× |
125+
| `groupby_having_count` | 142.2 | 2.4 | 2.5 | 1.04× |
126+
| `groupby_having_hidden_sum` | 176.1 | 2.5 | 2.8 | 1.12× |
127+
| `groupby_having_post_where` | 171.1 | 2.4 | 2.7 | 1.13× |
128+
| `groupby_max` | 173.5 | 2.4 | 2.7 | 1.13× |
129+
| `groupby_min` | 177.0 | 2.4 | 2.7 | 1.13× |
130+
| `groupby_multi_reducer` | 190.9 | 2.7 | 3.0 | 1.11× |
131+
| `groupby_select_order` | 170.7 | 2.4 | 2.7 | 1.13× |
132+
| `groupby_select_sum` | 204.2 | 3.2 | 3.7 | 1.16× |
133+
| `groupby_sum` | 170.7 | 2.4 | 2.7 | 1.13× |
134+
| `groupby_where_count` | 75.3 | 1.5 | 1.8 | 1.20× |
135+
| `groupby_where_sum` | 86.4 | 1.5 | 1.8 | 1.20× |
136+
| `indexed_lookup` | 1264.3 | 35429.3 | 108.0 | 0.00× |
137+
| `join_count` | 37.8 | 34.4 | 12.8 | 0.37× |
138+
| `join_groupby_count` || 47.2 | 21.9 | 0.46× |
139+
| `join_groupby_to_array` || 54.5 | 21.8 | 0.40× |
140+
| `join_select` || 41.9 | 22.7 | 0.54× |
141+
| `join_where_count` | 39.2 | 41.5 | 22.9 | 0.55× |
141142
| `last_match` | 0.00 | 0.50 | 1.4 | 2.80× |
142-
| `long_count_aggregate` | 29.3 | 0.40 | 0.60 | 1.50× |
143-
| `max_aggregate` | 30.6 | 0.60 | 0.50 | 0.83× |
144-
| `min_aggregate` | 30.5 | 0.60 | 0.50 | 0.83× |
143+
| `long_count_aggregate` | 29.2 | 0.40 | 0.60 | 1.50× |
144+
| `max_aggregate` | 30.7 | 0.60 | 0.50 | 0.83× |
145+
| `min_aggregate` | 30.7 | 0.60 | 0.50 | 0.83× |
145146
| `order_distinct_take` || 2.1 |||
146-
| `order_reverse_normalized` | 38.0 | 0.70 | 1.3 | 1.86× |
147-
| `order_take_desc` | 37.8 | 0.70 | 1.3 | 1.86× |
147+
| `order_reverse_normalized` | 37.9 | 0.70 | 1.4 | 2.00× |
148+
| `order_take_desc` | 38.2 | 0.70 | 1.4 | 2.00× |
148149
| `reverse_take` | 0.00 | 0.00 | 1.1 ||
149-
| `reverse_take_select` | 0.00 | 8.4 | 10.4 | 1.24× |
150+
| `reverse_take_select` | 0.00 | 8.4 | 10.2 | 1.21× |
150151
| `select_count` | 0.10 | 0.00 | 0.00 ||
151-
| `select_where` | 104.4 | 4.2 | 5.6 | 1.33× |
152-
| `select_where_count` | 32.6 | 0.40 | 0.60 | 1.50× |
153-
| `select_where_order_take` | 36.3 | 0.70 | 1.4 | 2.00× |
154-
| `select_where_sum` | 37.1 | 0.50 | 0.60 | 1.20× |
152+
| `select_where` | 104.2 | 4.2 | 5.5 | 1.31× |
153+
| `select_where_count` | 32.2 | 0.40 | 0.60 | 1.50× |
154+
| `select_where_order_take` | 36.4 | 0.70 | 1.4 | 2.00× |
155+
| `select_where_sum` | 36.9 | 0.50 | 0.60 | 1.20× |
155156
| `single_match` | 0.00 | 0.40 | 1.1 | 2.75× |
156157
| `skip_take` | 0.30 | 0.00 | 0.00 ||
157158
| `skip_while_match` | 3.4 | 0.40 | 0.40 | 1.00× |
158159
| `sort_first` | 37.6 | 0.40 | 1.3 | 3.25× |
159-
| `sort_take` | 38.0 | 0.70 | 1.3 | 1.86× |
160-
| `sort_take_select` | 37.9 | 0.70 | 1.3 | 1.86× |
161-
| `sum_aggregate` | 29.9 | 0.40 | 0.30 | 0.75× |
162-
| `sum_where` | 32.9 | 0.40 | 0.60 | 1.50× |
160+
| `sort_take` | 38.1 | 0.70 | 1.3 | 1.86× |
161+
| `sort_take_select` | 37.9 | 0.70 | 1.4 | 2.00× |
162+
| `sum_aggregate` | 29.8 | 0.40 | 0.30 | 0.75× |
163+
| `sum_where` | 32.6 | 0.40 | 0.60 | 1.50× |
163164
| `take_count` | 1.8 | 0.10 | 0.10 | 1.00× |
164165
| `take_count_filtered` || 0.00 | 0.00 ||
165166
| `take_sum_aggregate` || 0.00 | 0.00 ||
166167
| `take_where_count` || 0.00 | 10.3 ||
167168
| `take_while_match` | 7.8 | 0.20 | 0.30 | 1.50× |
168-
| `to_array_filter` | 47.8 | 3.3 | 3.4 | 1.03× |
169+
| `to_array_filter` | 47.2 | 3.3 | 3.4 | 1.03× |
169170
| `zip_count_pred` || 0.70 |||
170171
| `zip_dot_product` || 0.50 | 0.50 | 1.00× |
171172
| `zip_dot_product_3arg` || 0.50 |||

daslib/linq.das

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ def long_count(var a : iterator<auto(TT)>) : int64 {
852852

853853
def long_count(a : array<auto(TT)>) : int64 {
854854
//! Counts elements in an array, using a long integer
855-
return int64(length(a))
855+
return long_length(a)
856856
}
857857

858858
def long_count(var a : iterator<auto(TT)>; predicate : block<(arg : TT -&) : bool>) : int64 {

0 commit comments

Comments
 (0)