Skip to content

Commit

Permalink
[SPARK-12771][SQL] Simplify CaseWhen code generation
Browse files Browse the repository at this point in the history
The generated code for CaseWhen uses a control variable "got" to make sure we do not evaluate more branches once a branch is true. Changing that to generate just simple "if / else" would be slightly more efficient.

This closes #10737.

Author: Reynold Xin <[email protected]>

Closes #10755 from rxin/SPARK-12771.
  • Loading branch information
rxin committed Jan 14, 2016
1 parent 501e99e commit 902667f
Showing 1 changed file with 35 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -137,45 +137,55 @@ case class CaseWhen(branches: Seq[(Expression, Expression)], elseValue: Option[E
}

override def genCode(ctx: CodeGenContext, ev: GeneratedExpressionCode): String = {
val got = ctx.freshName("got")

val cases = branches.map { case (condition, value) =>
val cond = condition.gen(ctx)
val res = value.gen(ctx)
// Generate code that looks like:
//
// condA = ...
// if (condA) {
// valueA
// } else {
// condB = ...
// if (condB) {
// valueB
// } else {
// condC = ...
// if (condC) {
// valueC
// } else {
// elseValue
// }
// }
// }
val cases = branches.map { case (condExpr, valueExpr) =>
val cond = condExpr.gen(ctx)
val res = valueExpr.gen(ctx)
s"""
if (!$got) {
${cond.code}
if (!${cond.isNull} && ${cond.value}) {
$got = true;
${res.code}
${ev.isNull} = ${res.isNull};
${ev.value} = ${res.value};
}
${cond.code}
if (!${cond.isNull} && ${cond.value}) {
${res.code}
${ev.isNull} = ${res.isNull};
${ev.value} = ${res.value};
}
"""
}.mkString("\n")
}

val elseCase = {
if (elseValue.isDefined) {
val res = elseValue.get.gen(ctx)
var generatedCode = cases.mkString("", "\nelse {\n", "\nelse {\n")

elseValue.foreach { elseExpr =>
val res = elseExpr.gen(ctx)
generatedCode +=
s"""
if (!$got) {
${res.code}
${ev.isNull} = ${res.isNull};
${ev.value} = ${res.value};
}
"""
} else {
""
}
}

generatedCode += "}\n" * cases.size

s"""
boolean $got = false;
boolean ${ev.isNull} = true;
${ctx.javaType(dataType)} ${ev.value} = ${ctx.defaultValue(dataType)};
$cases
$elseCase
$generatedCode
"""
}

Expand Down

0 comments on commit 902667f

Please sign in to comment.