Files
ClickHouse/tests/performance/aggregate_function_for_each.xml
Groene AIandClaude Opus 5.5 4c121f75a2 Keep the direct nested call for arrays of 0 or 1 elements in -ForEach
The batch call costs one virtual call per row, which is more than the
zero or one per-element `add` calls it replaces for empty and
single-element arrays. Measured with `sumForEach` on 2M rows (query_log
wall medians, base vs fix): calling the batch unconditionally made empty
arrays 10-49% and single-element arrays up to 20% slower; with this
threshold both stay within noise (mean +1.2%), while 32-element arrays
keep their 34-61% speedup.

Add a short-array table (0 to 3 elements) and two queries to
`aggregate_function_for_each.xml`, appended after the existing ones so
their indices do not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 06:59:26 +00:00

31 lines
1.7 KiB
XML

<test>
<!-- The `-ForEach` combinator accumulates one nested state per array element. A Memory source
keeps the wide Array column read from dominating, so the combinator itself is measured. -->
<create_query>CREATE TABLE for_each_bench (k UInt32, arr Array(Float64)) ENGINE = Memory</create_query>
<fill_query>INSERT INTO for_each_bench
SELECT number % 1000, arrayMap(i -> toFloat64(i + number), range(32))
FROM numbers(2000000)
</fill_query>
<!-- single place: addBatchSinglePlace -->
<query>SELECT sumForEach(arr) FROM for_each_bench FORMAT Null</query>
<query>SELECT avgForEach(arr) FROM for_each_bench FORMAT Null</query>
<query>SELECT quantilesForEach(0.5, 0.9)(arr) FROM for_each_bench FORMAT Null</query>
<!-- many places: addBatch -->
<query>SELECT k, sumForEach(arr) FROM for_each_bench GROUP BY k FORMAT Null</query>
<query>SELECT k, quantilesForEach(0.5, 0.9)(arr) FROM for_each_bench GROUP BY k FORMAT Null</query>
<!-- short arrays (0 to 3 elements) -->
<create_query>CREATE TABLE for_each_bench_short (k UInt32, arr Array(Float64)) ENGINE = Memory</create_query>
<fill_query>INSERT INTO for_each_bench_short
SELECT number % 1000, arrayMap(i -> toFloat64(i + number), range(number % 4))
FROM numbers(10000000)
</fill_query>
<query>SELECT sumForEach(arr) FROM for_each_bench_short FORMAT Null</query>
<query>SELECT k, sumForEach(arr) FROM for_each_bench_short GROUP BY k FORMAT Null</query>
<drop_query>DROP TABLE IF EXISTS for_each_bench</drop_query>
<drop_query>DROP TABLE IF EXISTS for_each_bench_short</drop_query>
</test>