Apache spark 为什么Spark SQL UDF比RDD慢?

Apache spark 为什么Spark SQL UDF比RDD慢?,apache-spark,pyspark,Apache Spark,Pyspark,我需要对成对对象的数据帧执行一些昂贵的分析。设置如下所示 # This does the expensive work and holds some reference data # Expensive to initialize so done only once analyze = Analyze() def analyze_row(row): # Turn the row into objects and pass them to the function above f

我需要对成对对象的数据帧执行一些昂贵的分析。设置如下所示

# This does the expensive work and holds some reference data
# Expensive to initialize so done only once
analyze = Analyze()

def analyze_row(row):
    # Turn the row into objects and pass them to the function above
    foo = Foo.from_dict(row.foo.asDict(recursive=True))
    bar = Bar.from_dict(row.bar.asDict(recursive=True))
    return analyze(foo, bar)
当我像这样将
analyze\u row
作为自定义项应用时

analyze_row_udf = udf(analyze_row, result_schema)
results_df = input_df.withColumn("result", analyze_row_udf).select("result.*")
从经验上讲,它比将其应用于RDD(如图所示)要慢

results = content.rdd.map(analyze_row)
results_df = spark.createDataFrame(results, schema=result_schema)
在其他条件相同的情况下,UDF版本似乎没有在一小时内取得进展,而RDD版本则在30分钟内完成。在这两种情况下,群集CPU都已耗尽。在多次尝试中重复了相同的行为


我认为数据帧应该取代RDD,部分原因是它的性能更好。为什么在这种情况下RDD看起来要快得多?

数据帧可以取代RDD,其中:

  • 存在执行计划优化(此处无法应用任何优化)
  • 使用了一些低级优化—堆外内存、代码生成(当您在JVM之外执行黑盒代码时,同样不应用任何优化)
  • 使用优化的列存储-(同上)
此外,在上下文之间传递数据的成本很高,合并部分结果需要额外的操作。而且它的内存需求增加了一倍多

很难说为什么RDD在您的案例中严格地更快(有显著的改进,而且您没有提供版本),但我猜您遇到了一些案例边界

总的来说,对于任意Python代码来说,数据帧根本不是一个更好的选择。这在将来可能会有所改变,因为使用Arrow支持向量化操作