MaxGekk commented on code in PR #59047:
URL: https://github.com/apache/spark/pull/59047#discussion_r4126765367
##########
docs/sql-performance-tuning.md:
##########
@@ -400,6 +400,29 @@
spark.sql.optimizer.excludedRules=org.apache.spark.sql.execution.planmerging.Mer
Use exactly that name: the rule was called `MergeScalarSubqueries` before
Spark 4.2 and sat in a different package before Spark 4.3, and unknown names in
`spark.sql.optimizer.excludedRules` are silently ignored, so an older name
carried over from a previous version does not turn the rule off. See the [SQL
migration guide](sql-migration-guide.html) for the old names.
+## Whole-Stage Code Generation
+
+Whole-stage code generation combines operators into generated Java methods. On
HotSpot JVMs with
+`-XX:+DontCompileHugeMethods` enabled (the default), methods larger than 8000
bytes are not JIT
+compiled. If a generated method is too large, consider lowering the following
limit to `8000` so
+Spark runs the affected subtree without whole-stage code generation. Compare
performance on your
+workload before retaining the setting; disabling whole-stage code generation
can also reduce
+performance.
+
+<table class="spark-config">
+<thead><tr><th>Property Name</th><th>Default</th><th>Meaning</th><th>Since
Version</th></tr></thead>
+<tr>
+ <td><code>spark.sql.codegen.hugeMethodLimit</code></td>
+ <td>65535</td>
+ <td>
+ Maximum bytecode size of a compiled Java method generated by whole-stage
code generation.
+ If a compiled method exceeds this limit, Spark disables whole-stage code
generation for that
Review Comment:
At the default this never happens. The check in
`WholeStageCodegenExec.doExecute` is `maxMethodCodeSize > hugeMethodLimit`, and
a JVM method's code is capped at 65535 bytes by the class-file format, so a
method past the default never reaches the check: Janino refuses to assemble the
class ("Code grows beyond 64 KB") and the query takes the other fallback,
`spark.sql.codegen.fallback`. As written, the row reads as if the default
protects against oversized methods.
Could the meaning say that the setting acts only when set below 65535?
Something like: "Maximum bytecode size of a method generated by whole-stage
code generation. When a generated method exceeds this limit, Spark runs that
codegen stage without whole-stage code generation. The default, 65535, is the
JVM's own cap on a method's size, so the check has no effect until the limit is
lowered; 8000 is HotSpot's JIT limit (see above)."
##########
docs/sql-performance-tuning.md:
##########
@@ -400,6 +400,29 @@
spark.sql.optimizer.excludedRules=org.apache.spark.sql.execution.planmerging.Mer
Use exactly that name: the rule was called `MergeScalarSubqueries` before
Spark 4.2 and sat in a different package before Spark 4.3, and unknown names in
`spark.sql.optimizer.excludedRules` are silently ignored, so an older name
carried over from a previous version does not turn the rule off. See the [SQL
migration guide](sql-migration-guide.html) for the old names.
+## Whole-Stage Code Generation
+
+Whole-stage code generation combines operators into generated Java methods. On
HotSpot JVMs with
+`-XX:+DontCompileHugeMethods` enabled (the default), methods larger than 8000
bytes are not JIT
+compiled. If a generated method is too large, consider lowering the following
limit to `8000` so
+Spark runs the affected subtree without whole-stage code generation. Compare
performance on your
+workload before retaining the setting; disabling whole-stage code generation
can also reduce
+performance.
+
+<table class="spark-config">
+<thead><tr><th>Property Name</th><th>Default</th><th>Meaning</th><th>Since
Version</th></tr></thead>
+<tr>
+ <td><code>spark.sql.codegen.hugeMethodLimit</code></td>
Review Comment:
`spark.sql.codegen.hugeMethodLimit` is `.internal()`, and the description
says so. Internal configs carry no compatibility promise and are left out of
the generated config docs on purpose, so documenting one in the tuning table
invites users to depend on it. I'd rather do one of two things: drop
`.internal()` in this PR, since the table makes it public in effect, or keep it
out of the table and mention it in the prose as an advanced setting that may
change. Which do you prefer?
##########
docs/sql-performance-tuning.md:
##########
@@ -400,6 +400,29 @@
spark.sql.optimizer.excludedRules=org.apache.spark.sql.execution.planmerging.Mer
Use exactly that name: the rule was called `MergeScalarSubqueries` before
Spark 4.2 and sat in a different package before Spark 4.3, and unknown names in
`spark.sql.optimizer.excludedRules` are silently ignored, so an older name
carried over from a previous version does not turn the rule off. See the [SQL
migration guide](sql-migration-guide.html) for the old names.
+## Whole-Stage Code Generation
+
+Whole-stage code generation combines operators into generated Java methods. On
HotSpot JVMs with
+`-XX:+DontCompileHugeMethods` enabled (the default), methods larger than 8000
bytes are not JIT
+compiled. If a generated method is too large, consider lowering the following
limit to `8000` so
+Spark runs the affected subtree without whole-stage code generation. Compare
performance on your
Review Comment:
Two things here. On the over-limit path `WholeStageCodegenExec` returns
`child.execute()`, so what is disabled is that one codegen stage; below it, the
`InputAdapter` nodes wrap further stages that keep running their generated
code. "Subtree" suggests more than that (the `SQLConf` doc string has the same
wording, but this guide is where users form the picture).
And the reader has no way to know whether a method is too large: Spark logs
it at INFO on every compile of such a class, `Generated method too long to be
JIT compiled: <class>.<method> is <N> bytes` (`CodeGenerator`). I'd say: "Spark
logs `Generated method too long to be JIT compiled` when this happens. If you
see it, consider lowering the limit below to 8000, so that a codegen stage with
such a method runs without whole-stage code generation; the stages above and
below it still use it. Compare performance on your workload first: a method
just past 8000 bytes can still be faster compiled than the fallback, while one
far past it runs interpreted and is many times slower."
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]