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]

Reply via email to