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

dongjoon-hyun pushed a commit to branch branch-4.x
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-4.x by this push:
     new 2787aa198271 [SPARK-57935][SQL][TEST] Add `DecimalDivideBenchmark`
2787aa198271 is described below

commit 2787aa198271c951d6f8681c3350f59bb84d73cd
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]>
    (cherry picked from commit 6ff24ad5157a310faec92c79e8b7b6de54b31847)
    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]

Reply via email to