This is an automated email from the ASF dual-hosted git repository.

andygrove pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-ballista.git


The following commit(s) were added to refs/heads/main by this push:
     new 99ba9e860 docs: refresh SF1000 benchmark results on 2x16-core AQE-on 
reference cluster (#2109)
99ba9e860 is described below

commit 99ba9e86031e748b7bffe33cf9061d2c61058c92
Author: Andy Grove <[email protected]>
AuthorDate: Mon Jul 20 17:07:29 2026 -0600

    docs: refresh SF1000 benchmark results on 2x16-core AQE-on reference 
cluster (#2109)
    
    * docs: refresh SF1000 benchmark results on 2x16-core AQE-on reference 
cluster
    
    Update the benchmarking page to a single official configuration: TPC-H 
SF1000
    on 2 executors of 16 cores each, target_partitions=64, 1 iteration, AQE on.
    Drop the AQE-off column and its planner discussion, since only AQE on is
    measured going forward. Refresh the Spark, Comet, and Ballista result table
    and the pinned versions, and record Q18 as OOM on Ballista at this sizing.
    
    * docs: apply prettier formatting to benchmarking tables
---
 docs/source/contributors-guide/benchmarking.md | 176 ++++++++++++++-----------
 1 file changed, 98 insertions(+), 78 deletions(-)

diff --git a/docs/source/contributors-guide/benchmarking.md 
b/docs/source/contributors-guide/benchmarking.md
index a066f0aa0..7dde09788 100644
--- a/docs/source/contributors-guide/benchmarking.md
+++ b/docs/source/contributors-guide/benchmarking.md
@@ -38,16 +38,15 @@ stage is only as fast as its slowest task, so a query whose 
work concentrates on
 a few partitions will underperform no matter how fast the underlying operators 
are.
 Benchmarks are therefore run at a scale where that imbalance actually shows up.
 
-Two configurations are always measured, because they select **different 
planners**
-with materially different join behaviour:
+These benchmarks are run with **adaptive query execution (AQE) enabled**
+(`ballista.planner.adaptive.enabled=true`). This is the configuration Ballista 
is
+being actively developed against, so it is the one measured here.
 
-- **AQE off** (`ballista.planner.adaptive.enabled=false`, the default) — the 
static
-  `DefaultDistributedPlanner`.
-- **AQE on** (`ballista.planner.adaptive.enabled=true`, experimental) — the 
adaptive
-  planner, which can re-plan stages using runtime statistics.
-
-A change that helps one planner can be a no-op or a regression under the 
other, so
-results are reported for both rather than for whichever looks better.
+AQE selects the adaptive planner, which can re-plan stages using runtime 
statistics —
+coalescing partitions, re-optimising joins, and promoting a small join side to 
a
+broadcast at runtime. The alternative, AQE off, selects the static
+`DefaultDistributedPlanner`; it is a different planner with materially 
different join
+behaviour, and it is no longer benchmarked on this page.
 
 ## Environment
 
@@ -76,14 +75,14 @@ All results on this page use the following shape. It is a 
reference point, not a
 requirement — the commands below work on any cluster, but numbers are only
 comparable when the shape matches.
 
-|                     |                                            |
-| ------------------- | ------------------------------------------ |
-| Executors           | 2, one per physical node                   |
-| Per executor        | 8 cores, 56 GiB, `--memory-pool-size=48GB` |
-| Per task slot       | 8 concurrent tasks → 6 GB pool each        |
-| Scheduler           | 1                                          |
-| Data                | TPC-H SF1000 Parquet, node-local disk      |
-| `target_partitions` | 32                                         |
+|                     |                                             |
+| ------------------- | ------------------------------------------- |
+| Executors           | 2, one per physical node                    |
+| Per executor        | 16 cores, 56 GiB, `--memory-pool-size=48GB` |
+| Per task slot       | 16 concurrent tasks → 3 GB pool each        |
+| Scheduler           | 1                                           |
+| Data                | TPC-H SF1000 Parquet, node-local disk       |
+| `target_partitions` | 64                                          |
 
 Two details matter more than they look:
 
@@ -149,14 +148,17 @@ tpch benchmark ballista \
   --host <scheduler> --port 50050 \
   --query 18 \
   --path /mnt/bigdata/tpch/sf1000 --format parquet \
-  --partitions 32 --iterations 1 \
+  --partitions 64 --iterations 1 \
   -c datafusion.optimizer.prefer_hash_join=false \
   -c datafusion.optimizer.enable_dynamic_filter_pushdown=false \
   -c ballista.planner.adaptive.enabled=true
 ```
 
-Omit `--query` to run all 22. Flip `ballista.planner.adaptive.enabled` to 
`false`
-for the AQE-off number.
+Omit `--query` to run all 22. `ballista.planner.adaptive.enabled=true` is the 
AQE-on
+configuration these results use.
+
+`prefer_hash_join=false` makes DataFusion plan joins as `SortMergeJoin`, which 
is the
+join strategy this page compares across engines (Comet is configured to match, 
below).
 
 Note `datafusion.optimizer.enable_dynamic_filter_pushdown=false`: DataFusion's
 dynamic filter pushdown assumes single-process execution and can deadlock
@@ -171,7 +173,7 @@ Spark runs the same queries via `tpcbench.py` from
 spark-submit \
   --master <master> \
   --conf spark.executor.instances=2 \
-  --conf spark.executor.cores=8 \
+  --conf spark.executor.cores=16 \
   --conf spark.executor.memory=32G \
   --conf spark.executor.memoryOverhead=8G \
   --conf spark.memory.offHeap.enabled=true \
@@ -202,11 +204,11 @@ spark-submit \
   --conf spark.executor.extraClassPath=$COMET_JAR \
   --conf spark.plugins=org.apache.spark.CometPlugin \
   --conf 
spark.shuffle.manager=org.apache.spark.sql.comet.execution.shuffle.CometShuffleManager
 \
-  --conf spark.comet.exec.replaceSortMergeJoin=true \
+  --conf spark.comet.exec.replaceSortMergeJoin=false \
   --conf spark.comet.exec.memoryPool=fair_unified \
   --conf spark.comet.exec.memoryPool.fraction=0.8 \
   --conf spark.executor.instances=2 \
-  --conf spark.executor.cores=8 \
+  --conf spark.executor.cores=16 \
   --conf spark.executor.memory=32G \
   --conf spark.executor.memoryOverhead=8G \
   --conf spark.memory.offHeap.enabled=true \
@@ -219,6 +221,11 @@ spark-submit \
     --query 18
 ```
 
+`spark.comet.exec.replaceSortMergeJoin=false` keeps Comet on Spark's 
`SortMergeJoin`
+instead of converting it to a shuffled hash join. This matches Ballista, which 
plans
+`SortMergeJoin` (`prefer_hash_join=false`), so the two engines are compared on 
the
+same join strategy rather than one being handed a different one.
+
 [comet]: https://datafusion.apache.org/comet/
 
 ## Why compare against Comet
@@ -256,62 +263,74 @@ planner.
 
 ## Results
 
-TPC-H **SF1000**, reference cluster above, 1 iteration, `target_partitions=32`,
-`prefer_hash_join=false`, `enable_dynamic_filter_pushdown=false`. Times in 
seconds;
-lower is better.
+TPC-H **SF1000**, reference cluster above, **AQE on**, 1 iteration,
+`target_partitions=64`, `prefer_hash_join=false`,
+`enable_dynamic_filter_pushdown=false`. All three engines plan 
`SortMergeJoin`. Times
+in seconds; lower is better.
 
 Versions under test:
 
-| Engine   | Version                         |
-| -------- | ------------------------------- |
-| Ballista | `main` @ `26b29391`             |
-| Spark    | 3.5.3 (vanilla, Comet disabled) |
-| Comet    | 0.17.0                          |
-
-Pinning the Ballista commit rather than "main" matters: `26b29391` removed the
-static planner's sort-merge-join broadcast conversion, which changes the 
AQE-off
-path specifically. A number from before that commit is not comparable to one 
after
-it, and only the exact commit makes that visible.
-
-Every figure is from a **full 22-query suite run** — one query after another 
in a
-single session, on freshly started executors.
-
-|     Query |      Spark |      Comet | Ballista (AQE off) | Ballista (AQE on) 
|   Rows |
-| --------: | ---------: | ---------: | -----------------: | ----------------: 
| -----: |
-|         1 |      444.8 |       49.3 |               70.8 |              36.2 
|      4 |
-|         2 |       74.3 |       37.3 |              155.5 |              63.6 
|    100 |
-|         3 |      158.4 |       99.1 |              206.2 |             255.0 
|     10 |
-|         4 |      104.1 |       42.3 |               76.8 |              53.9 
|      5 |
-|         5 |      364.9 |      234.6 |              542.7 |             700.5 
|      5 |
-|         6 |       22.0 |       15.3 |               18.3 |              12.7 
|      1 |
-|         7 |      196.1 |      141.8 |              575.5 |             531.4 
|      4 |
-|         8 |      412.7 |      291.6 |              657.1 |             801.2 
|      2 |
-|         9 |      570.2 |      392.1 |              891.8 |            1025.2 
|    175 |
-|        10 |      147.3 |      112.5 |              240.3 |             166.7 
|     20 |
-|        11 |       58.3 |       48.7 |              105.1 |              76.2 
|  0 [1] |
-|        12 |       75.9 |       52.9 |               79.4 |              85.2 
|      2 |
-|        13 |      114.1 |       71.9 |               96.7 |              95.6 
|     30 |
-|        14 |       44.6 |       29.0 |               38.0 |              34.3 
|      1 |
-|        15 |      108.9 |       63.8 |               45.9 |              52.7 
| \* [2] |
-|        16 |       33.9 |       18.7 |               21.9 |              23.0 
|  27840 |
-|        17 |      519.5 |      308.2 |              697.8 |             400.4 
|      1 |
-|        18 |      492.8 |      234.2 |              620.7 |             820.9 
|    100 |
-|        19 |       53.7 |       39.4 |               39.6 |              42.1 
|      1 |
-|        20 |      108.1 |       74.6 |               80.5 |              82.9 
| 110759 |
-|        21 |      536.4 |      351.4 |             1083.0 |             926.6 
|    100 |
-|        22 |       47.0 |       29.8 |               34.9 |              34.6 
|      7 |
-| **Total** | **4687.9** | **2738.5** |         **6378.2** |        **6320.7** 
|        |
-
-**All 22 queries completed on all four configurations**; there are no failures 
to
-report. Row counts agreed across every engine except Q15.
+| Engine   | Version                                         |
+| -------- | ----------------------------------------------- |
+| Ballista | `main` @ `49d1fec8`                             |
+| Spark    | 3.5.3 (vanilla, Comet disabled)                 |
+| Comet    | `main` @ `b0165552` (1.0.0-SNAPSHOT, Spark 3.5) |
+
+Pin the **exact commit** the numbers came from, not "main": `main` moves, and 
a row
+that mixes numbers from different commits silently misattributes a regression.
+
+Ballista Q1–Q17 come from a **full 22-query suite run** (one query after 
another on
+freshly started executors); Q18 exhausts the memory pool and OOM-kills the 
executors
+(see below), which currently wedges the rest of the suite, so **Q19–Q22 were 
run as
+individual single-query jobs** against a fresh cluster of the same shape. 
Comet and
+Spark each completed the full suite in one run.
+
+|                 Query |      Spark |      Comet | Ballista (AQE on) |   Rows 
|
+| --------------------: | ---------: | ---------: | ----------------: | -----: 
|
+|                     1 |      427.1 |       46.6 |              21.4 |      4 
|
+|                     2 |       75.9 |       39.2 |              64.1 |    100 
|
+|                     3 |      154.1 |      195.4 |             202.5 |     10 
|
+|                     4 |       82.0 |       42.6 |              54.6 |      5 
|
+|                     5 |      336.4 |      493.4 |             474.7 |      5 
|
+|                     6 |       28.9 |       14.6 |              27.7 |      1 
|
+|                     7 |      180.6 |      149.5 |             457.0 |      4 
|
+|                     8 |      391.8 |      642.1 |             731.0 |      2 
|
+|                     9 |      509.8 |      843.5 |             934.3 |    175 
|
+|                    10 |      151.1 |      104.8 |             136.8 |     20 
|
+|                    11 |       44.7 |       44.1 |              85.4 |  0 [1] 
|
+|                    12 |       74.1 |       49.9 |              70.9 |      2 
|
+|                    13 |       98.7 |       58.3 |              92.5 |     30 
|
+|                    14 |       43.0 |       27.4 |              38.9 |      1 
|
+|                    15 |      121.5 |       65.6 |              84.5 |  1 [2] 
|
+|                    16 |       24.5 |       17.5 |              24.3 |  27840 
|
+|                    17 |      406.7 |      285.8 |             355.3 |      1 
|
+|                    18 |      428.8 |      370.5 |               OOM |    100 
|
+|                    19 |       58.9 |       35.5 |             120.4 |      1 
|
+|                    20 |      105.9 |       67.6 |             111.2 | 110759 
|
+|                    21 |      562.2 |      460.1 |             694.7 |    100 
|
+|                    22 |       36.8 |       21.5 |              35.6 |      7 
|
+| **Total (excl. Q18)** | **3914.7** | **3705.0** |        **4817.8** |        
|
+
+The **Total** row sums the 21 queries **excluding Q18**, because Q18 does not 
complete
+on Ballista at this sizing (below), so a 22-query total would not be 
comparable across
+engines. Q18's own times are in its row.
+
+Row counts agree across all three engines on every query, including Q18 (Spark 
and
+Comet return 100; Ballista OOMs before producing a result).
 
 [1] Q11 returns 0 rows for every engine at this scale factor: the query's 
threshold
 constant is tuned for SF1.
 
-[2] **Row counts disagree on Q15: Spark returns 0, Comet and Ballista both 
return 1.** Q15 is a multi-statement query (`CREATE VIEW` / `SELECT` / `DROP 
VIEW`), and
-how many rows a harness reports depends on which statement it takes as the 
result.
-Recorded rather than resolved: it is not established which count is correct, or
-whether the engines computed different answers at all.
+[2] Q15 is a multi-statement query (`CREATE VIEW` / `SELECT` / `DROP VIEW`); 
all three
+engines report 1 row here. (A previous result set saw Spark report 0 for Q15 
depending
+on which statement the harness took as the result; it does not recur in this 
run.)
+
+**Q18 OOMs on Ballista at this sizing.** Q18's hash-join build side is 
`Partitioned`
+and does not spill; with 16 task slots sharing the 48 GB pool (3 GB per slot), 
the
+per-task build side exceeds the container limit and the executor is OOM-killed
+([#2025](https://github.com/apache/datafusion-ballista/issues/2025)). At the 
previous
+8-slot sizing (6 GB per slot) Q18 completed, so this is a direct consequence 
of the
+denser packing. The OOM is recorded as `OOM` rather than a time.
 
 The `Rows` column is the row count the query returned, recorded so a time is 
never
 read without the answer it produced.
@@ -328,12 +347,13 @@ known memory exhaustion.
 ### Recording a result
 
 - Pin the **exact commit** the numbers came from, not a branch name.
-- Report **AQE on and AQE off** from the **same** commit and cluster. 
Comparing an
-  AQE-on number against an AQE-off number from an older build attributes the 
build
-  difference to the planner.
-- Take the figure from a **full suite run**, not a standalone single-query 
run. The
-  two differ measurably: a long-lived executor deep into a suite is not in the 
same
-  state as a freshly started one.
+- Report the **AQE-on** number (`ballista.planner.adaptive.enabled=true`) — the
+  configuration this page measures — from the same commit and cluster.
+- Prefer the figure from a **full suite run**, not a standalone single-query 
run: a
+  long-lived executor deep into a suite is not in the same state as a freshly 
started
+  one. When a query cannot complete in-suite (e.g. Q18's OOM currently wedges 
the
+  run), note that the remaining queries were run individually, as done here for
+  Q19–Q22.
 - Note the **row count** each query returned. A fast wrong answer is not a 
result,
   and distributed execution has produced silently wrong row counts before.
 - Flag any stage whose runtime is dominated by a few partitions — that is the


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to