11# Benchmarks — SQL / Array / Decs comparison
22
3- Generated 2026-05-27 from PR ` bbatkin/sqlite-linq-distinct-by-aggregates ` (sqlite_linq ` _distinct_by ` as chain operator + first-row aggregates). Two SQL ` — ` cells now populated: ` order_distinct_take ` m1 = 139.2 INTERP / 138.2 JIT via a new 1-column ` Brand ` table fixture (named-tuple projection lets ` _sql ` lower to clean ` SELECT DISTINCT "value" FROM "Brands" ORDER BY "value" ASC LIMIT ? ` ); ` distinct_count_pred ` m1 = 253.1 INTERP / 252.8 JIT via the new bare-aggregate ` _distinct_by(K) |> _count(P) ` wrap (lowers to ` SELECT COUNT(*) FROM (SELECT *, MIN("id") FROM "Cars" GROUP BY "brand") WHERE "year" > ? ` ). The remaining SQL ` — ` cells stay catalogued in [ ` sqlite_linq_gaps.md ` ] ( sqlite_linq_gaps.md ) . Other drift is bench-suite ordering noise: ` distinct_by_order_take ` m4 INTERP 23.4 → 30.9 (+32%), ` groupby_select_order ` m4 INTERP 18.7 → 24.2 (+29%), ` select_where_order_take ` m3f/m4 INTERP ±6-8% — same long-running pattern as prior PRs; sub-nanosecond JIT cells drift at measurement floor.
3+ Generated 2026-05-27 from PR ` bbatkin/sqlite-linq-distinct-by-composition ` (sqlite_linq ` _distinct_by ` composition + ` reverse() |> _distinct_by ` MAX(pk) + ` _group_by |> first() ` row projection). Four SQL ` — ` cells now populated, draining the entire "window-function lowerings" group from [ ` sqlite_linq_gaps.md ` ] ( sqlite_linq_gaps.md ) — none of them actually needed window functions, all lower via SQLite's bare-aggregate optimization with outer ORDER BY / LIMIT or MAX(pk) variant:
4+ - ` distinct_by_order_take ` m1 = 240.5 INTERP / 253.6 JIT
5+ - ` distinct_by_order_to_array ` m1 = 240.6 INTERP / 239.3 JIT
6+ - ` reverse_distinct_by ` m1 = 312.5 INTERP / 297.1 JIT (MAX(pk) variant)
7+ - ` groupby_first ` m1 = 255.1 INTERP / 252.4 JIT (tuple-with-row projection)
8+
9+ Drift is minor and mostly converges back toward pre- #2906 baselines: ` distinct_by_order_take ` m4 INTERP 30.9 → 23.8 (-23%) and ` groupby_select_order ` m4 INTERP 24.2 → 18.8 (-22%) reverse the post- #2906 drift entries. ` indexed_lookup ` m4 now populated (482.9 INTERP / 107.5 JIT) — earlier ` — ` was stale bench-output parsing. Remaining JIT cells drift ±5% at measurement floor.
410Fixture size: n = 100 000 (cars), 100 dealers, 5 brands. Each row is
511one bench family in ` benchmarks/sql/ ` ; columns are nanoseconds per
612logical operation. ` — ` marks an intentionally absent lane — see
@@ -27,157 +33,156 @@ before the timer resolution can measure them — they should be read as
2733
2834| Benchmark | SQL (m1) | Array (m3f) | Decs (m4) | Decs vs Array |
2935| ---| ---:| ---:| ---:| ---:|
30- | ` aggregate_match ` | 35.3 | 6.1 | 5.9 | 0.97 × |
31- | ` all_match ` | 28.1 | 3.5 | 3.5 | 1.00 × |
36+ | ` aggregate_match ` | 34.8 | 6.0 | 5.9 | 0.98 × |
37+ | ` all_match ` | 27.8 | 3.6 | 3.5 | 0.97 × |
3238| ` any_match ` | 0.00 | 0.00 | 0.00 | — |
33- | ` average_aggregate ` | 30.5 | 5.9 | 8.8 | 1.49× |
34- | ` bare_order_where ` | 279 .7 | 116.5 | 124.8 | 1.07 × |
35- | ` chained_select_collapse ` | — | 17.9 | 17.7 | 0.99 × |
36- | ` chained_where ` | 37.0 | 6.7 | 7.1 | 1.06× |
39+ | ` average_aggregate ` | 30.2 | 5.9 | 8.8 | 1.49× |
40+ | ` bare_order_where ` | 276 .7 | 117.6 | 123.5 | 1.05 × |
41+ | ` chained_select_collapse ` | — | 17.9 | 17.6 | 0.98 × |
42+ | ` chained_where ` | 36.9 | 6.7 | 7.1 | 1.06× |
3743| ` contains_match ` | 0.00 | 2.2 | 1.4 | 0.64× |
38- | ` count_aggregate ` | 30.0 | 4.2 | 4.1 | 0.98× |
44+ | ` count_aggregate ` | 29.8 | 4.2 | 4.1 | 0.98× |
3945| ` decs_count_bare_pred ` | — | — | 4.2 | — |
40- | ` distinct_by_count ` | 41.8 | 15.8 | 15.8 | 1.00× |
41- | ` distinct_by_order_take ` | — | 21.8 | 30.9 | 1.42 × |
42- | ` distinct_by_order_to_array ` | — | 22.0 | 24.0 | 1.09 × |
43- | ` distinct_count ` | 41.7 | 16.0 | 15.9 | 0.99× |
44- | ` distinct_count_pred ` | 253.1 | 15.9 | 16.0 | 1.01 × |
46+ | ` distinct_by_count ` | 41.4 | 15.7 | 15.7 | 1.00× |
47+ | ` distinct_by_order_take ` | 240.5 | 21.9 | 23.8 | 1.09 × |
48+ | ` distinct_by_order_to_array ` | 240.6 | 22.2 | 23.3 | 1.05 × |
49+ | ` distinct_count ` | 42.0 | 16.1 | 15.9 | 0.99× |
50+ | ` distinct_count_pred ` | 253.2 | 15.8 | 16.1 | 1.02 × |
4551| ` distinct_take ` | 0.00 | 0.00 | 0.00 | — |
4652| ` element_at_match ` | 0.00 | 0.00 | 0.00 | — |
4753| ` first_match ` | 0.00 | 0.00 | 0.00 | — |
4854| ` first_or_default_match ` | 0.00 | 0.00 | 0.00 | — |
49- | ` groupby_average ` | 171.9 | 30.3 | 30.2 | 1.00 × |
50- | ` groupby_count ` | 142.9 | 19.4 | 19.2 | 0.99 × |
51- | ` groupby_first ` | — | 18.5 | 19.2 | 1.04× |
52- | ` groupby_having_count ` | 142.4 | 19.3 | 19.2 | 0.99× |
53- | ` groupby_having_hidden_sum ` | 175.2 | 24.1 | 24.4 | 1.01 × |
54- | ` groupby_having_post_where ` | 172.9 | 18.5 | 18.7 | 1.01× |
55- | ` groupby_max ` | 174.2 | 25.0 | 25.6 | 1.02 × |
56- | ` groupby_min ` | 176.3 | 25.0 | 25.2 | 1.01× |
57- | ` groupby_multi_reducer ` | 190.1 | 32.5 | 33.0 | 1.02 × |
58- | ` groupby_select_order ` | 171 .4 | 18.6 | 24.2 | 1.30 × |
59- | ` groupby_select_sum ` | 200.9 | 36.5 | 35.9 | 0.98× |
60- | ` groupby_sum ` | 172.6 | 18.8 | 18.8 | 1.00 × |
61- | ` groupby_where_count ` | 75.9 | 14.5 | 15.0 | 1.03× |
62- | ` groupby_where_sum ` | 86.9 | 14.2 | 14.6 | 1.03 × |
63- | ` indexed_lookup ` | 1468.7 | 204087.0 | 475 .9 | 0.00× |
64- | ` join_count ` | 38.5 | 121.4 | 64.1 | 0.53× |
65- | ` join_groupby_count ` | — | 186.2 | 91.0 | 0.49× |
66- | ` join_groupby_to_array ` | — | 216.7 | 90.7 | 0.42 × |
67- | ` join_select ` | — | 149.4 | 85.2 | 0.57 × |
68- | ` join_where_count ` | 39.4 | 148.9 | 74.4 | 0.50× |
69- | ` last_match ` | 0.00 | 5.8 | 14.1 | 2.43 × |
70- | ` long_count_aggregate ` | 30.0 | 4.2 | 4.1 | 0.98× |
71- | ` max_aggregate ` | 31.4 | 6.0 | 6.9 | 1.15× |
72- | ` min_aggregate ` | 31.5 | 6.2 | 6.9 | 1.11 × |
73- | ` order_distinct_take ` | 139 .2 | 15.8 | 95.5 | 6.04 × |
74- | ` order_reverse_normalized ` | 38.6 | 16.3 | 20.0 | 1.23 × |
75- | ` order_take_desc ` | 38.5 | 16.2 | 19.9 | 1.23 × |
76- | ` reverse_distinct_by ` | — | 21.5 | — | — |
77- | ` reverse_take ` | 0.10 | 0.00 | 10.2 | — |
78- | ` reverse_take_select ` | 0.00 | 34.3 | 48.4 | 1.41 × |
79- | ` select_count ` | 0.10 | 0.00 | 2.2 | — |
80- | ` select_where ` | 195.7 | 11.3 | 19.9 | 1.76 × |
81- | ` select_where_count ` | 33.3 | 5.2 | 7.5 | 1.44 × |
82- | ` select_where_order_take ` | 37.0 | 12.3 | 14.9 | 1.21 × |
83- | ` select_where_sum ` | 37.3 | 7.6 | 7.6 | 1.00× |
84- | ` single_match ` | 0.00 | 2.9 | 5.5 | 1.90 × |
85- | ` skip_take ` | 0.50 | 0.10 | 0.20 | 2.00× |
86- | ` skip_while_match ` | 3.5 | 5.3 | 5.3 | 1.00 × |
87- | ` sort_first ` | 38.3 | 11.1 | 13.4 | 1.21 × |
88- | ` sort_take ` | 38.7 | 16.4 | 20.7 | 1.26 × |
89- | ` sort_take_select ` | 38.6 | 16.2 | 20.1 | 1.24× |
90- | ` sum_aggregate ` | 30.1 | 2.2 | 2.1 | 0.95× |
91- | ` sum_where ` | 33.2 | 4.3 | 4.2 | 0.98 × |
92- | ` take_count ` | 3.6 | 0.20 | 0.40 | 2.00 × |
93- | ` take_count_filtered ` | — | 0.20 | 0.20 | 1.00× |
94- | ` take_sum_aggregate ` | — | 0.10 | 0.10 | 1.00× |
95- | ` take_where_count ` | — | 0.10 | 0.10 | 1.00× |
96- | ` take_while_match ` | 7.9 | 2.4 | 2.4 | 1.00× |
97- | ` to_array_filter ` | 71.0 | 11.7 | 11.8 | 1.01× |
98- | ` zip_count_pred ` | — | 15.1 | — | — |
99- | ` zip_dot_product ` | — | 12.7 | 10.7 | 0.84× |
100- | ` zip_dot_product_3arg ` | — | 12.8 | — | — |
101- | ` zip_reverse_to_array ` | — | 31.1 | — | — |
55+ | ` groupby_average ` | 172.6 | 30.1 | 30.3 | 1.01 × |
56+ | ` groupby_count ` | 142.5 | 19.4 | 19.5 | 1.01 × |
57+ | ` groupby_first ` | 255.1 | 18.5 | 19.2 | 1.04× |
58+ | ` groupby_having_count ` | 143.0 | 19.3 | 19.2 | 0.99× |
59+ | ` groupby_having_hidden_sum ` | 176.0 | 23.8 | 24.4 | 1.03 × |
60+ | ` groupby_having_post_where ` | 172.7 | 18.6 | 18.8 | 1.01× |
61+ | ` groupby_max ` | 175.5 | 25.2 | 25.2 | 1.00 × |
62+ | ` groupby_min ` | 173.2 | 25.5 | 25.8 | 1.01× |
63+ | ` groupby_multi_reducer ` | 191.2 | 32.1 | 32.5 | 1.01 × |
64+ | ` groupby_select_order ` | 175 .4 | 18.6 | 18.8 | 1.01 × |
65+ | ` groupby_select_sum ` | 202.2 | 36.5 | 35.8 | 0.98× |
66+ | ` groupby_sum ` | 175.9 | 18.7 | 18.6 | 0.99 × |
67+ | ` groupby_where_count ` | 75.5 | 14.5 | 14.9 | 1.03× |
68+ | ` groupby_where_sum ` | 86.4 | 14.2 | 14.5 | 1.02 × |
69+ | ` indexed_lookup ` | 1442.6 | 202815.2 | 482 .9 | 0.00× |
70+ | ` join_count ` | 38.5 | 120.6 | 64.0 | 0.53× |
71+ | ` join_groupby_count ` | — | 186.6 | 91.7 | 0.49× |
72+ | ` join_groupby_to_array ` | — | 217.1 | 92.6 | 0.43 × |
73+ | ` join_select ` | — | 148.7 | 85.8 | 0.58 × |
74+ | ` join_where_count ` | 39.4 | 147.2 | 74.2 | 0.50× |
75+ | ` last_match ` | 0.00 | 5.8 | 14.0 | 2.41 × |
76+ | ` long_count_aggregate ` | 29.7 | 4.2 | 4.1 | 0.98× |
77+ | ` max_aggregate ` | 31.3 | 6.0 | 6.9 | 1.15× |
78+ | ` min_aggregate ` | 31.2 | 6.1 | 6.9 | 1.13 × |
79+ | ` order_distinct_take ` | 140 .2 | 15.9 | 94.8 | 5.96 × |
80+ | ` order_reverse_normalized ` | 38.4 | 16.2 | 20.1 | 1.24 × |
81+ | ` order_take_desc ` | 38.4 | 16.0 | 20.0 | 1.25 × |
82+ | ` reverse_distinct_by ` | 312.5 | 21.8 | — | — |
83+ | ` reverse_take ` | 0.1 | 0.00 | 10.1 | — |
84+ | ` reverse_take_select ` | 0.00 | 34.6 | 48.4 | 1.40 × |
85+ | ` select_count ` | 0.1 | 0.00 | 2.2 | — |
86+ | ` select_where ` | 193.8 | 11.3 | 19.8 | 1.75 × |
87+ | ` select_where_count ` | 33.1 | 5.2 | 7.4 | 1.42 × |
88+ | ` select_where_order_take ` | 37.0 | 12.3 | 15.0 | 1.22 × |
89+ | ` select_where_sum ` | 37.3 | 7.5 | 7.5 | 1.00× |
90+ | ` single_match ` | 0.00 | 2.9 | 5.6 | 1.93 × |
91+ | ` skip_take ` | 0.5 | 0.1 | 0.2 | 2.00× |
92+ | ` skip_while_match ` | 3.5 | 5.2 | 5.3 | 1.02 × |
93+ | ` sort_first ` | 38.1 | 11.0 | 13.5 | 1.23 × |
94+ | ` sort_take ` | 38.7 | 16.5 | 20.7 | 1.25 × |
95+ | ` sort_take_select ` | 38.4 | 16.1 | 20.0 | 1.24× |
96+ | ` sum_aggregate ` | 30.2 | 2.2 | 2.1 | 0.95× |
97+ | ` sum_where ` | 32.9 | 4.3 | 4.3 | 1.00 × |
98+ | ` take_count ` | 3.6 | 0.2 | 0.5 | 2.50 × |
99+ | ` take_count_filtered ` | — | 0.2 | 0.2 | 1.00× |
100+ | ` take_sum_aggregate ` | — | 0.1 | 0.1 | 1.00× |
101+ | ` take_where_count ` | — | 0.1 | 0.1 | 1.00× |
102+ | ` take_while_match ` | 7.8 | 2.4 | 2.4 | 1.00× |
103+ | ` to_array_filter ` | 70.2 | 11.7 | 11.8 | 1.01× |
104+ | ` zip_count_pred ` | — | 15.2 | — | — |
105+ | ` zip_dot_product ` | — | 12.6 | 10.6 | 0.84× |
106+ | ` zip_dot_product_3arg ` | — | 12.7 | — | — |
107+ | ` zip_reverse_to_array ` | — | 31.2 | — | — |
102108
103109## JIT
104110
105111| Benchmark | SQL (m1) | Array (m3f) | Decs (m4) | Decs vs Array |
106112| ---| ---:| ---:| ---:| ---:|
107- | ` aggregate_match ` | 35.2 | 0.40 | 0.70 | 1.75× |
108- | ` all_match ` | 27.9 | 0.30 | 0.20 | 0.67× |
113+ | ` aggregate_match ` | 34.8 | 0.4 | 0.7 | 1.75× |
114+ | ` all_match ` | 27.7 | 0.3 | 0.2 | 0.67× |
109115| ` any_match ` | 0.00 | 0.00 | 0.00 | — |
110- | ` average_aggregate ` | 30.5 | 1.0 | 3.6 | 3.60× |
111- | ` bare_order_where ` | 187.3 | 34.2 | 35.2 | 1.03 × |
116+ | ` average_aggregate ` | 30.2 | 1.0 | 3.6 | 3.60× |
117+ | ` bare_order_where ` | 185.6 | 34.1 | 34.1 | 1.00 × |
112118| ` chained_select_collapse ` | — | 2.1 | 2.1 | 1.00× |
113- | ` chained_where ` | 36.7 | 0.60 | 0.90 | 1.50× |
114- | ` contains_match ` | 0.00 | 0.20 | 0.10 | 0.50× |
115- | ` count_aggregate ` | 29.6 | 0.40 | 0.60 | 1.50× |
116- | ` decs_count_bare_pred ` | — | — | 0.60 | — |
117- | ` distinct_by_count ` | 41.4 | 2.1 | 2.1 | 1.00× |
118- | ` distinct_by_order_take ` | — | 2.7 | 3.2 | 1.19 × |
119- | ` distinct_by_order_to_array ` | — | 2.7 | 3.3 | 1.22 × |
120- | ` distinct_count ` | 41.5 | 2.1 | 2.1 | 1.00× |
121- | ` distinct_count_pred ` | 252.8 | 2.1 | 2.3 | 1.10× |
122- | ` distinct_take ` | 0.00 | 0.00 | 0.00 | — |
119+ | ` chained_where ` | 36.9 | 0.6 | 0.9 | 1.50× |
120+ | ` contains_match ` | 0.00 | 0.2 | 0.1 | 0.50× |
121+ | ` count_aggregate ` | 29.7 | 0.4 | 0.6 | 1.50× |
122+ | ` decs_count_bare_pred ` | — | — | 0.6 | — |
123+ | ` distinct_by_count ` | 42.0 | 2.1 | 2.1 | 1.00× |
124+ | ` distinct_by_order_take ` | 253.6 | 2.6 | 3.2 | 1.23 × |
125+ | ` distinct_by_order_to_array ` | 239.3 | 2.7 | 3.2 | 1.19 × |
126+ | ` distinct_count ` | 42.2 | 2.1 | 2.1 | 1.00× |
127+ | ` distinct_count_pred ` | 253.0 | 2.1 | 2.3 | 1.10× |
128+ | ` distinct_take ` | 0.00 | 0.1 | 0.00 | 0.00× |
123129| ` element_at_match ` | 0.00 | 0.00 | 0.00 | — |
124130| ` first_match ` | 0.00 | 0.00 | 0.00 | — |
125131| ` first_or_default_match ` | 0.00 | 0.00 | 0.00 | — |
126- | ` groupby_average ` | 172.8 | 2.6 | 2.9 | 1.12× |
127- | ` groupby_count ` | 142.0 | 2.4 | 2.5 | 1.04× |
128- | ` groupby_first ` | — | 2.2 | 3.1 | 1.41× |
129- | ` groupby_having_count ` | 142.4 | 2.3 | 2.5 | 1.09 × |
130- | ` groupby_having_hidden_sum ` | 176.4 | 2.5 | 2.8 | 1.12× |
131- | ` groupby_having_post_where ` | 171 .4 | 2.4 | 2.7 | 1.13× |
132- | ` groupby_max ` | 175.4 | 2.4 | 2.7 | 1.13× |
133- | ` groupby_min ` | 174.0 | 2.4 | 2.7 | 1.13× |
134- | ` groupby_multi_reducer ` | 190.5 | 2.7 | 3.0 | 1.11× |
135- | ` groupby_select_order ` | 171.9 | 2.4 | 2.7 | 1.13× |
136- | ` groupby_select_sum ` | 200.4 | 3.2 | 3.7 | 1.16× |
137- | ` groupby_sum ` | 172.1 | 2.4 | 2.7 | 1.13× |
138- | ` groupby_where_count ` | 75.8 | 1.5 | 1.8 | 1.20× |
139- | ` groupby_where_sum ` | 87.5 | 1.5 | 1.8 | 1.20× |
140- | ` indexed_lookup ` | 1249.3 | 35189 .7 | 105.7 | 0.00× |
141- | ` join_count ` | 38.6 | 34.5 | 13.0 | 0.38 × |
142- | ` join_groupby_count ` | — | 47.5 | 21.9 | 0.46× |
143- | ` join_groupby_to_array ` | — | 56.1 | 21.9 | 0.39 × |
144- | ` join_select ` | — | 41.7 | 22.7 | 0.54× |
145- | ` join_where_count ` | 39.4 | 41.5 | 22.7 | 0.55× |
146- | ` last_match ` | 0.00 | 0.50 | 1.4 | 2.80× |
147- | ` long_count_aggregate ` | 29.9 | 0.40 | 0.60 | 1.50× |
148- | ` max_aggregate ` | 31.3 | 0.60 | 0.50 | 0.83× |
149- | ` min_aggregate ` | 31.2 | 0.60 | 0.50 | 0.83× |
150- | ` order_distinct_take ` | 138.2 | 2.1 | 74.9 | 35.67 × |
151- | ` order_reverse_normalized ` | 38.3 | 0.70 | 1.3 | 1.86× |
152- | ` order_take_desc ` | 38.4 | 0.70 | 1.3 | 1.86× |
153- | ` reverse_distinct_by ` | — | 2.6 | — | — |
132+ | ` groupby_average ` | 171.9 | 2.6 | 2.9 | 1.12× |
133+ | ` groupby_count ` | 142.9 | 2.4 | 2.5 | 1.04× |
134+ | ` groupby_first ` | 252.4 | 2.2 | 3.1 | 1.41× |
135+ | ` groupby_having_count ` | 142.3 | 2.4 | 2.5 | 1.04 × |
136+ | ` groupby_having_hidden_sum ` | 176.1 | 2.5 | 2.8 | 1.12× |
137+ | ` groupby_having_post_where ` | 172 .4 | 2.4 | 2.7 | 1.13× |
138+ | ` groupby_max ` | 173.8 | 2.4 | 2.7 | 1.13× |
139+ | ` groupby_min ` | 181.6 | 2.4 | 2.7 | 1.13× |
140+ | ` groupby_multi_reducer ` | 190.9 | 2.7 | 3.0 | 1.11× |
141+ | ` groupby_select_order ` | 171.5 | 2.4 | 2.7 | 1.13× |
142+ | ` groupby_select_sum ` | 199.7 | 3.2 | 3.7 | 1.16× |
143+ | ` groupby_sum ` | 172.5 | 2.4 | 2.7 | 1.13× |
144+ | ` groupby_where_count ` | 76.2 | 1.5 | 1.8 | 1.20× |
145+ | ` groupby_where_sum ` | 86.9 | 1.5 | 1.8 | 1.20× |
146+ | ` indexed_lookup ` | 1265.6 | 35161 .7 | 107.5 | 0.00× |
147+ | ` join_count ` | 38.4 | 34.5 | 12.8 | 0.37 × |
148+ | ` join_groupby_count ` | — | 47.1 | 21.9 | 0.46× |
149+ | ` join_groupby_to_array ` | — | 54.7 | 21.9 | 0.40 × |
150+ | ` join_select ` | — | 41.8 | 22.6 | 0.54× |
151+ | ` join_where_count ` | 39.5 | 41.5 | 22.9 | 0.55× |
152+ | ` last_match ` | 0.00 | 0.5 | 1.4 | 2.80× |
153+ | ` long_count_aggregate ` | 29.5 | 0.4 | 0.6 | 1.50× |
154+ | ` max_aggregate ` | 31.1 | 0.6 | 0.5 | 0.83× |
155+ | ` min_aggregate ` | 31.2 | 0.6 | 0.5 | 0.83× |
156+ | ` order_distinct_take ` | 138.7 | 2.1 | 75.1 | 35.76 × |
157+ | ` order_reverse_normalized ` | 38.3 | 0.7 | 1.3 | 1.86× |
158+ | ` order_take_desc ` | 38.2 | 0.7 | 1.3 | 1.86× |
159+ | ` reverse_distinct_by ` | 297.1 | 2.7 | — | — |
154160| ` reverse_take ` | 0.00 | 0.00 | 1.1 | — |
155- | ` reverse_take_select ` | 0.00 | 8.5 | 10.5 | 1.24 × |
156- | ` select_count ` | 0.10 | 0.00 | 0.00 | — |
157- | ` select_where ` | 108.0 | 4.2 | 5.6 | 1.33× |
158- | ` select_where_count ` | 33.1 | 0.40 | 0.60 | 1.50× |
159- | ` select_where_order_take ` | 36.7 | 0.70 | 1.3 | 1.86 × |
160- | ` select_where_sum ` | 37.2 | 0.50 | 0.60 | 1.20× |
161- | ` single_match ` | 0.00 | 0.40 | 1.1 | 2.75× |
162- | ` skip_take ` | 0.30 | 0.00 | 0.00 | — |
163- | ` skip_while_match ` | 3.5 | 0.40 | 0.40 | 1.00× |
164- | ` sort_first ` | 38.3 | 0.40 | 1.3 | 3.25× |
165- | ` sort_take ` | 38.6 | 0.70 | 1.4 | 2.00× |
166- | ` sort_take_select ` | 38.5 | 0.80 | 1.4 | 1.75 × |
167- | ` sum_aggregate ` | 30.4 | 0.40 | 0.30 | 0.75× |
168- | ` sum_where ` | 34.7 | 0.40 | 0.60 | 1.50× |
169- | ` take_count ` | 1.8 | 0.10 | 0.10 | 1.00× |
161+ | ` reverse_take_select ` | 0.00 | 8.7 | 11.2 | 1.29 × |
162+ | ` select_count ` | 0.1 | 0.00 | 0.00 | — |
163+ | ` select_where ` | 106.1 | 4.3 | 5.7 | 1.33× |
164+ | ` select_where_count ` | 32.9 | 0.4 | 0.6 | 1.50× |
165+ | ` select_where_order_take ` | 36.8 | 0.7 | 1.4 | 2.00 × |
166+ | ` select_where_sum ` | 37.6 | 0.5 | 0.6 | 1.20× |
167+ | ` single_match ` | 0.00 | 0.4 | 1.1 | 2.75× |
168+ | ` skip_take ` | 0.3 | 0.00 | 0.00 | — |
169+ | ` skip_while_match ` | 3.5 | 0.4 | 0.4 | 1.00× |
170+ | ` sort_first ` | 38.2 | 0.4 | 1.3 | 3.25× |
171+ | ` sort_take ` | 38.3 | 0.7 | 1.4 | 2.00× |
172+ | ` sort_take_select ` | 38.4 | 0.7 | 1.4 | 2.00 × |
173+ | ` sum_aggregate ` | 30.4 | 0.4 | 0.3 | 0.75× |
174+ | ` sum_where ` | 32.9 | 0.4 | 0.6 | 1.50× |
175+ | ` take_count ` | 1.8 | 0.1 | 0.1 | 1.00× |
170176| ` take_count_filtered ` | — | 0.00 | 0.00 | — |
171177| ` take_sum_aggregate ` | — | 0.00 | 0.00 | — |
172178| ` take_where_count ` | — | 0.00 | 0.00 | — |
173- | ` take_while_match ` | 7.8 | 0.20 | 0.30 | 1.50× |
174- | ` to_array_filter ` | 48.4 | 3.3 | 3.4 | 1.03× |
175- | ` zip_count_pred ` | — | 0.70 | — | — |
176- | ` zip_dot_product ` | — | 0.50 | 0.50 | 1.00× |
177- | ` zip_dot_product_3arg ` | — | 0.50 | — | — |
179+ | ` take_while_match ` | 7.8 | 0.2 | 0.3 | 1.50× |
180+ | ` to_array_filter ` | 48.3 | 3.3 | 3.4 | 1.03× |
181+ | ` zip_count_pred ` | — | 0.7 | — | — |
182+ | ` zip_dot_product ` | — | 0.5 | 0.5 | 1.00× |
183+ | ` zip_dot_product_3arg ` | — | 0.5 | — | — |
178184| ` zip_reverse_to_array ` | — | 4.5 | — | — |
179185
180-
181186## Notes on missing lanes (the ` — ` cells)
182187
183188The reasons each cell is empty are also recorded as a comment in the
@@ -196,20 +201,6 @@ and which gaps could land in a single PR — see
196201 ` forExpr.iteratorVariables ` was unpopulated). Array-side bare ` count(P) `
197202 was always reachable; SQL ` count(P) ` is covered by ` count_aggregate.das `
198203 with a where shape. By design.
199- - ** ` distinct_by_order_take ` SQL** — no faithful SQL form. "Pick one row
200- per dealer, sort by price, take N" needs window functions
201- (` ROW_NUMBER() OVER (PARTITION BY dealer_id ORDER BY price) ` + outer
202- ` WHERE rn=1 ` + ` LIMIT N ` ); sqlite_linq does not currently lower window
203- functions. Follow-up TODO 2026-05-25 — see ` sqlite_linq_gaps.md `
204- "Window-function lowerings".
205- - ** ` distinct_by_order_to_array ` SQL** — same window-function blocker as
206- ` distinct_by_order_take ` , drop the ` LIMIT N ` . See
207- ` sqlite_linq_gaps.md ` "Window-function lowerings".
208- - ** ` groupby_first ` SQL** — no direct SQL aggregator for "first
209- source-order row per group". Window functions (`ROW_NUMBER() OVER
210- (PARTITION BY brand ORDER BY id)` + outer ` WHERE rn=1`) would be the
211- SQL equivalent; sqlite_linq does not currently lower window
212- functions. Follow-up TODO 2026-05-23.
213204- ** ` indexed_lookup ` Decs vs Array ratio** — the ratio is reported as
214205 ` 0.00× ` because array's lane measures the unspliced linear scan
215206 (~ 204k ns/op), while decs uses ` query(eid) ` for O(1) lookup. The
@@ -223,13 +214,10 @@ and which gaps could land in a single PR — see
223214 bare ` _ ` (only the ` into ` lambda's parameter names are valid
224215 receivers; computed projections would need to be inlined into the
225216 ` into ` lambda). By design — sqlite_linq surface limitation.
226- - ** ` reverse_distinct_by ` SQL / Decs** — SQL: same window-function
227- blocker as ` distinct_by_order_take ` , with descending key
228- (` ROW_NUMBER() OVER (PARTITION BY brand ORDER BY id DESC) WHERE rn=1 `
229- picks "last-per-group"); see ` sqlite_linq_gaps.md ` . Decs: splice arm
230- is array-only (` array_source ` predicate in
231- ` daslib/linq_fold.das:3221 ` ) because backward-index walk has no
232- archetype analog.
217+ - ** ` reverse_distinct_by ` Decs** — splice arm is array-only
218+ (` array_source ` predicate in ` daslib/linq_fold.das:3221 ` ) because
219+ backward-index walk has no archetype analog. SQL lane closed by
220+ Arm B of this PR via MAX(pk) bare-aggregate.
233221- ** ` order_distinct_take ` Decs vs Array ratio** — m4 (95.5 INTERP /
234222 74.9 JIT) vs m3f (15.8 INTERP / 2.1 JIT) is NOT apples-to-apples.
235223 ` unique_key ` (` daslib/linq.das:614 ` ) short-circuits to a direct
0 commit comments