This is an automated email from the ASF dual-hosted git repository.
dongjoon-hyun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/master by this push:
new 6ff24ad5157a [SPARK-57935][SQL][TEST] Add `DecimalDivideBenchmark`
6ff24ad5157a is described below
commit 6ff24ad5157a310faec92c79e8b7b6de54b31847
Author: Dongjoon Hyun <[email protected]>
AuthorDate: Sun Jul 5 02:43:33 2026 -0700
[SPARK-57935][SQL][TEST] Add `DecimalDivideBenchmark`
### What changes were proposed in this pull request?
This PR adds `DecimalDivideBenchmark`, measuring per-row Decimal division
(`select a / b`) with ANSI mode off and on for:
- `decimal(7,2) / decimal(7,2)` — compact Long representation case
- `decimal(38,18) / decimal(38,18)` — BigDecimal representation case
- each shape also with an integer-literal divisor (`a / 2`, the TPC-DS q4
`year_total` shape)
Divisors are generated non-null and `>= 1` so the divide-by-zero branch is
not measured.
### Why are the changes needed?
To measure `per-row Decimal division cost`. Please note that this is a
baseline to compare the future update.
### Does this PR introduce _any_ user-facing change?
No.
### How was this patch tested?
Pass the CIs.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Fable 5
Closes #57002 from dongjoon-hyun/SPARK-57935.
Authored-by: Dongjoon Hyun <[email protected]>
Signed-off-by: Dongjoon Hyun <[email protected]>
---
.../DecimalDivideBenchmark-jdk21-results.txt | 23 ++++++
.../DecimalDivideBenchmark-jdk25-results.txt | 23 ++++++
.../benchmarks/DecimalDivideBenchmark-results.txt | 23 ++++++
.../benchmark/DecimalDivideBenchmark.scala | 86 ++++++++++++++++++++++
4 files changed, 155 insertions(+)
diff --git a/sql/core/benchmarks/DecimalDivideBenchmark-jdk21-results.txt
b/sql/core/benchmarks/DecimalDivideBenchmark-jdk21-results.txt
new file mode 100644
index 000000000000..b449110256c4
--- /dev/null
+++ b/sql/core/benchmarks/DecimalDivideBenchmark-jdk21-results.txt
@@ -0,0 +1,23 @@
+================================================================================================
+Decimal division
+================================================================================================
+
+OpenJDK 64-Bit Server VM 21.0.11+10-LTS on Linux 6.17.0-1018-azure
+AMD EPYC 7763 64-Core Processor
+decimal(7,2) / decimal(7,2): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+a / b (ansi=false) 7797 7858
37 1.3 779.7 1.0X
+a / b (ansi=true) 7886 7904
18 1.3 788.6 1.0X
+a / 2 (ansi=false) 5524 5553
18 1.8 552.4 1.4X
+a / 2 (ansi=true) 5476 5500
24 1.8 547.6 1.4X
+
+OpenJDK 64-Bit Server VM 21.0.11+10-LTS on Linux 6.17.0-1018-azure
+AMD EPYC 7763 64-Core Processor
+decimal(38,18) / decimal(38,18): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+a / b (ansi=false) 14130 14148
11 0.7 1413.0 1.0X
+a / b (ansi=true) 14138 14146
6 0.7 1413.8 1.0X
+a / 2 (ansi=false) 8607 8628
27 1.2 860.7 1.6X
+a / 2 (ansi=true) 8579 8623
26 1.2 857.9 1.6X
+
+
diff --git a/sql/core/benchmarks/DecimalDivideBenchmark-jdk25-results.txt
b/sql/core/benchmarks/DecimalDivideBenchmark-jdk25-results.txt
new file mode 100644
index 000000000000..50913d8981d7
--- /dev/null
+++ b/sql/core/benchmarks/DecimalDivideBenchmark-jdk25-results.txt
@@ -0,0 +1,23 @@
+================================================================================================
+Decimal division
+================================================================================================
+
+OpenJDK 64-Bit Server VM 25.0.3+9-LTS on Linux 6.17.0-1018-azure
+AMD EPYC 9V45 96-Core Processor
+decimal(7,2) / decimal(7,2): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+a / b (ansi=false) 3110 3121
14 3.2 311.0 1.0X
+a / b (ansi=true) 3023 3070
36 3.3 302.3 1.0X
+a / 2 (ansi=false) 2088 2111
26 4.8 208.8 1.5X
+a / 2 (ansi=true) 2039 2065
30 4.9 203.9 1.5X
+
+OpenJDK 64-Bit Server VM 25.0.3+9-LTS on Linux 6.17.0-1018-azure
+AMD EPYC 9V45 96-Core Processor
+decimal(38,18) / decimal(38,18): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+a / b (ansi=false) 5557 5611
43 1.8 555.7 1.0X
+a / b (ansi=true) 5383 5437
43 1.9 538.3 1.0X
+a / 2 (ansi=false) 3275 3313
32 3.1 327.5 1.7X
+a / 2 (ansi=true) 3025 3082
35 3.3 302.5 1.8X
+
+
diff --git a/sql/core/benchmarks/DecimalDivideBenchmark-results.txt
b/sql/core/benchmarks/DecimalDivideBenchmark-results.txt
new file mode 100644
index 000000000000..ea91d089f6c4
--- /dev/null
+++ b/sql/core/benchmarks/DecimalDivideBenchmark-results.txt
@@ -0,0 +1,23 @@
+================================================================================================
+Decimal division
+================================================================================================
+
+OpenJDK 64-Bit Server VM 17.0.19+10-LTS on Linux 6.17.0-1018-azure
+AMD EPYC 7763 64-Core Processor
+decimal(7,2) / decimal(7,2): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+a / b (ansi=false) 9214 9273
35 1.1 921.4 1.0X
+a / b (ansi=true) 9287 9306
19 1.1 928.7 1.0X
+a / 2 (ansi=false) 6273 6296
21 1.6 627.3 1.5X
+a / 2 (ansi=true) 6257 6262
4 1.6 625.7 1.5X
+
+OpenJDK 64-Bit Server VM 17.0.19+10-LTS on Linux 6.17.0-1018-azure
+AMD EPYC 7763 64-Core Processor
+decimal(38,18) / decimal(38,18): Best Time(ms) Avg Time(ms)
Stdev(ms) Rate(M/s) Per Row(ns) Relative
+------------------------------------------------------------------------------------------------------------------------
+a / b (ansi=false) 15889 15898
9 0.6 1588.9 1.0X
+a / b (ansi=true) 15872 15896
18 0.6 1587.2 1.0X
+a / 2 (ansi=false) 9324 9341
13 1.1 932.4 1.7X
+a / 2 (ansi=true) 9307 9345
23 1.1 930.7 1.7X
+
+
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/execution/benchmark/DecimalDivideBenchmark.scala
b/sql/core/src/test/scala/org/apache/spark/sql/execution/benchmark/DecimalDivideBenchmark.scala
new file mode 100644
index 000000000000..180180c6f7b6
--- /dev/null
+++
b/sql/core/src/test/scala/org/apache/spark/sql/execution/benchmark/DecimalDivideBenchmark.scala
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.spark.sql.execution.benchmark
+
+import org.apache.spark.benchmark.Benchmark
+import org.apache.spark.sql.internal.SQLConf
+
+/**
+ * A benchmark that measures the performance of per-row Decimal division (`a /
b`).
+ *
+ * It covers a compact case (decimal(7,2) / decimal(7,2), result
decimal(17,10)) and an
+ * already-inflated case (decimal(38,18) / decimal(38,18), result
decimal(38,6)), each with
+ * ANSI mode off and on. Each case also measures division by an integer
literal (`a / 2`),
+ * the per-row shape used by TPC-DS q4's year_total. Divisors are generated
non-null and
+ * >= 1 so the divide-by-zero branch is never taken.
+ *
+ * To run this benchmark:
+ * {{{
+ * 1. without sbt:
+ * bin/spark-submit --class <this class>
+ * --jars <spark core test jar>,<spark catalyst test jar> <spark sql
test jar>
+ * 2. build/sbt "sql/Test/runMain <this class>"
+ * 3. generate result: SPARK_GENERATE_BENCHMARK_FILES=1 build/sbt
"sql/Test/runMain <this class>"
+ * Results will be written to
"benchmarks/DecimalDivideBenchmark-results.txt".
+ * }}}
+ */
+object DecimalDivideBenchmark extends SqlBasedBenchmark {
+
+ /**
+ * Division cases: (label, p, s, integral-part bound).
+ *
+ * `bound` caps the generated integral part so `rand() * bound + 1`
+ * stays within `decimal(p, s)`; the `+ 1` floor keeps every divisor
+ * non-zero.
+ */
+ private val DivideCases: Seq[(String, Int, Int, Long)] = Seq(
+ ("decimal(7,2) / decimal(7,2)", 7, 2, 99998L),
+ ("decimal(38,18) / decimal(38,18)", 38, 18, 99999998L)
+ )
+
+ private def setupDivideTable(n: Long, p: Int, s: Int, bound: Long): Unit = {
+ spark.range(n)
+ .selectExpr(
+ s"cast(rand(1) * $bound + 1 as decimal($p, $s)) as a",
+ s"cast(rand(2) * $bound + 1 as decimal($p, $s)) as b")
+ .coalesce(1)
+ .createOrReplaceTempView("t")
+ }
+
+ override def runBenchmarkSuite(mainArgs: Array[String]): Unit = {
+ val numRows: Long = if (mainArgs.length > 0) mainArgs(0).toLong else 10L *
1000L * 1000L
+ val iters: Int = if (mainArgs.length > 1) mainArgs(1).toInt else 5
+
+ runBenchmark("Decimal division") {
+ DivideCases.foreach { case (label, p, s, bound) =>
+ setupDivideTable(numRows, p, s, bound)
+ val bench = new Benchmark(label, numRows, output = output)
+ Seq("a / b", "a / 2").foreach { expr =>
+ Seq("false", "true").foreach { ansi =>
+ bench.addCase(s"$expr (ansi=$ansi)", numIters = iters) { _ =>
+ withSQLConf(SQLConf.ANSI_ENABLED.key -> ansi) {
+ spark.sql(s"select $expr from t").noop()
+ }
+ }
+ }
+ }
+ bench.run()
+ }
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]