diff options
author | Davies Liu <davies@databricks.com> | 2016-03-07 20:09:08 -0800 |
---|---|---|
committer | Davies Liu <davies.liu@gmail.com> | 2016-03-07 20:09:08 -0800 |
commit | 25bba58d160d0d24e40db1ca595200a52db922ed (patch) | |
tree | 9822c6c2f20af2a2faa68fd6d7e1d65921b2b877 /sql/catalyst | |
parent | da7bfac488b2a25c591986fe5f906b5c98dc34ea (diff) | |
download | spark-25bba58d160d0d24e40db1ca595200a52db922ed.tar.gz spark-25bba58d160d0d24e40db1ca595200a52db922ed.tar.bz2 spark-25bba58d160d0d24e40db1ca595200a52db922ed.zip |
[SPARK-13404] [SQL] Create variables for input row when it's actually used
## What changes were proposed in this pull request?
This PR change the way how we generate the code for the output variables passing from a plan to it's parent.
Right now, they are generated before call consume() of it's parent. It's not efficient, if the parent is a Filter or Join, which could filter out most the rows, the time to access some of the columns that are not used by the Filter or Join are wasted.
This PR try to improve this by defering the access of columns until they are actually used by a plan. After this PR, a plan does not need to generate code to evaluate the variables for output, just passing the ExprCode to its parent by `consume()`. In `parent.consumeChild()`, it will check the output from child and `usedInputs`, generate the code for those columns that is part of `usedInputs` before calling `doConsume()`.
This PR also change the `if` from
```
if (cond) {
xxx
}
```
to
```
if (!cond) continue;
xxx
```
The new one could help to reduce the nested indents for multiple levels of Filter and BroadcastHashJoin.
It also added some comments for operators.
## How was the this patch tested?
Unit tests. Manually ran TPCDS Q55, this PR improve the performance about 30% (scale=10, from 2.56s to 1.96s)
Author: Davies Liu <davies@databricks.com>
Closes #11274 from davies/gen_defer.
Diffstat (limited to 'sql/catalyst')
2 files changed, 6 insertions, 3 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/BoundAttribute.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/BoundAttribute.scala index 4727ff1885..72fe065459 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/BoundAttribute.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/BoundAttribute.scala @@ -62,9 +62,10 @@ case class BoundReference(ordinal: Int, dataType: DataType, nullable: Boolean) val javaType = ctx.javaType(dataType) val value = ctx.getValue(ctx.INPUT_ROW, dataType, ordinal.toString) if (ctx.currentVars != null && ctx.currentVars(ordinal) != null) { - ev.isNull = ctx.currentVars(ordinal).isNull - ev.value = ctx.currentVars(ordinal).value - "" + val oev = ctx.currentVars(ordinal) + ev.isNull = oev.isNull + ev.value = oev.value + oev.code } else if (nullable) { s""" boolean ${ev.isNull} = ${ctx.INPUT_ROW}.isNullAt($ordinal); diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala index 63e19564dd..c4265a7539 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala @@ -37,6 +37,8 @@ import org.apache.spark.util.Utils * Java source for evaluating an [[Expression]] given a [[InternalRow]] of input. * * @param code The sequence of statements required to evaluate the expression. + * It should be empty string, if `isNull` and `value` are already existed, or no code + * needed to evaluate them (literals). * @param isNull A term that holds a boolean value representing whether the expression evaluated * to null. * @param value A term for a (possibly primitive) value of the result of the evaluation. Not |