Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark apachespark中UDF的性能_Apache Spark_Apache Spark Sql - Fatal编程技术网

Apache spark apachespark中UDF的性能

Apache spark apachespark中UDF的性能,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我正在尝试做一个需要自定义函数的高性能计算 作为第一个阶段,我试图分析使用UDF的效果,我得到了奇怪的结果 我创建了一个简单的测试(在中) 基本上,我使用范围选项创建了一个数据帧,其中包含50万条记录,并将其缓存 然后我做了一个过滤器,找到那些小于10的,并对它们进行计数。一次通过列

我正在尝试做一个需要自定义函数的高性能计算

作为第一个阶段,我试图分析使用UDF的效果,我得到了奇怪的结果

我创建了一个简单的测试(在中)

基本上,我使用范围选项创建了一个数据帧,其中包含50万条记录,并将其缓存

然后我做了一个过滤器,找到那些小于10的,并对它们进行计数。一次通过列<10执行,一次通过UDF执行

每个动作我都运行了10次,以获得一个良好的时间估计

我发现这两种方法都需要大约相同的时间:~4秒

我还在我拥有的一个内部集群中进行了尝试(8个节点,使用纱线,每个节点都有大约40GB内存和大量内核)。第一个选项的结果是1秒,第二个选项的结果是8秒

首先,我不明白为什么在databricks集群上我获得了相同的性能。UDF不应该慢很多吗?毕竟,没有codegen,所以我应该看到一个慢得多的过程

其次,我不理解这两个集群之间的巨大差异:在一个集群中,我的时间几乎相同,而另一个集群的时间相差x8

最后,我试图找出如何以本机方式编写自定义函数(即spark的方式)。我试图查看spark的代码,得出了如下结论:

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是私有的)

这个代码的方向正确吗?我该怎么做


谢谢。

你有没有想过如何让它发挥作用?