2017-08-03 152 views
0

我有一些昂貴的分析需要在對象的DataFrame上執行。設置看起來像這樣。爲什麼Spark SQL UDF比RDD慢?

# 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_row作爲UDF像這樣

analyze_row_udf = udf(analyze_row, result_schema) 
results_df = input_df.withColumn("result", analyze_row_udf).select("result.*") 

它是憑經驗比它像這樣

results = content.rdd.map(analyze_row) 
results_df = spark.createDataFrame(results, schema=result_schema) 

所有其他條件相同,則UDF施加到RDD慢版本似乎沒有在一個小時內取得進展,而RDD版本在30分鐘內完成。在這兩種情況下,羣集CPU均已最大化。同樣的行爲在多次嘗試中被轉載。

我認爲DataFrames旨在取代RDD,部分原因是因爲性能更好。在這種情況下RDD似乎快得多?

回答

1

DataFrames可以取代其中RDDS:(可應用於這裏無)

  • 有執行計劃優化。
  • 有低級別的優化使用 - 斷堆內存,
  • 優化柱狀存儲用於碼生成(再一次,當你外JVM執行黑盒代碼沒有被施加) - (同上)。

此外,在上下文之間傳遞數據很昂貴,合併部分結果需要額外的操作。它也超過了內存需求的兩倍。

很難說爲什麼RDD在你的情況下嚴格更快(有顯着的改進時間,而你沒有提供版本),但我猜你碰到了一些案例邊界案例。

總的來說,對於任意Python代碼DataFrames根本不是更好的選擇。對於使用箭頭支持的矢量化操作,將來可能會有所改變。