Apache spark apachespark中UDF的性能
我正在尝试做一个需要自定义函数的高性能计算 作为第一个阶段,我试图分析使用UDF的效果,我得到了奇怪的结果 我创建了一个简单的测试(在中) 基本上,我使用范围选项创建了一个数据帧,其中包含50万条记录,并将其缓存 然后我做了一个过滤器,找到那些小于10的,并对它们进行计数。一次通过列<10执行,一次通过UDF执行 每个动作我都运行了10次,以获得一个良好的时间估计 我发现这两种方法都需要大约相同的时间:~4秒 我还在我拥有的一个内部集群中进行了尝试(8个节点,使用纱线,每个节点都有大约40GB内存和大量内核)。第一个选项的结果是1秒,第二个选项的结果是8秒 首先,我不明白为什么在databricks集群上我获得了相同的性能。UDF不应该慢很多吗?毕竟,没有codegen,所以我应该看到一个慢得多的过程 其次,我不理解这两个集群之间的巨大差异:在一个集群中,我的时间几乎相同,而另一个集群的时间相差x8 最后,我试图找出如何以本机方式编写自定义函数(即spark的方式)。我试图查看spark的代码,得出了如下结论:Apache spark apachespark中UDF的性能,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我正在尝试做一个需要自定义函数的高性能计算 作为第一个阶段,我试图分析使用UDF的效果,我得到了奇怪的结果 我创建了一个简单的测试(在中) 基本上,我使用范围选项创建了一个数据帧,其中包含50万条记录,并将其缓存 然后我做了一个过滤器,找到那些小于10的,并对它们进行计数。一次通过列
import org.apache.spark.sql.catalyst.InternalRow
import org.apache.spark.sql.catalyst.analysis.TypeCheckResult
import org.apache.spark.sql.catalyst.expressions.codegen.{CodegenContext, ExprCode}
import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
import org.apache.spark.sql.catalyst.util.TypeUtils
import org.apache.spark.sql.types._
import org.apache.spark.util.Utils
import org.apache.spark.sql.catalyst.expressions._
case class genf(child: Expression) extends UnaryExpression with Predicate with ImplicitCastInputTypes {
override def inputTypes: Seq[AbstractDataType] = Seq(IntegerType)
override def toString: String = s"$child < 10"
override def eval(input: InternalRow): Any = {
val value = child.eval(input)
if (value == null)
{
false
} else {
child.dataType match {
case IntegerType => value.asInstanceOf[Int] < 10
}
}
}
override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
defineCodeGen(ctx, ev, c => s"($c) < 10")
}
}
import org.apache.spark.sql.catalyst.InternalRow
导入org.apache.spark.sql.catalyst.analysis.TypeCheckResult
导入org.apache.spark.sql.catalyst.expressions.codegen.{CodegenContext,ExprCode}
导入org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
导入org.apache.spark.sql.catalyst.util.TypeUtils
导入org.apache.spark.sql.types.\u
导入org.apache.spark.util.Utils
导入org.apache.spark.sql.catalyst.expressions_
case类genf(child:Expression)扩展了带有ImplicitCastInputTypes谓词的一元表达式{
覆盖def输入类型:Seq[AbstractDataType]=Seq(IntegerType)
重写def toString:String=s“$child<10”
覆盖def eval(输入:InternalRow):Any={
val值=child.eval(输入)
如果(值==null)
{
假的
}否则{
child.dataType匹配{
case IntegerType=>value.asInstanceOf[Int]<10
}
}
}
覆盖def doGenCode(ctx:CodegenContext,ev:ExprCode):ExprCode={
定义(ctx、ev、c=>s“($c)<10”)
}
}
但是,这不起作用,因为它只在sql包中起作用(例如AbstractDataType是私有的)
这个代码的方向正确吗?我该怎么做
谢谢。你有没有想过如何让它发挥作用?