2017-12-02 90 views
0

我正在處理一個優化問題,該問題涉及在對象集合上最小化昂貴的地圖操作。火花短路,排序和懶惰地圖

天真溶液會是這樣的

rdd.map(expensive).min() 

然而,映射函數將返回保證是值> = 0。因此,如果任何一個的結果是0,I可以採取作爲答案和不需要計算其餘的地圖操作。

是否有使用Spark做到這一點的慣用方式?

回答

2

是否有一種使用Spark做到這一點的慣用方式?

不。如果你關心像這樣的低級優化,那麼Spark不是最好的選擇。這並不意味着它是完全不可能的。

如果你能舉例來說嘗試這樣的事情:

rdd.cache() 
(min_value,) = rdd.filter(lambda x: x == 0).take(1) or [rdd.min()] 
rdd.unpersist() 

短路分區:

def min_part(xs): 
    min_ = None 
    for x in xs: 
     min_ = min(x, min_) if min_ is not None else x 
     if x == 0: 
      return [0] 
    return [min_] in min_ is not None else [] 

rdd.mapPartitions(min_part).min() 

兩者通常將執行超過需要,每一種有稍微不同的性能配置,但可以跳過評估一些記錄。對於稀少的零來說,第一個可能會更好。

您甚至可以收聽累加器更新並在看到0時使用sc.cancelJobGroup。下面是類似的方法的一個例子Is there a way to stream results to driver without waiting for all partitions to complete execution?

0

如果「貴」是真的昂貴,也許你可以寫的「昂貴」,比方說,SQL的結果(或者提供給所有工人的任何其它存儲)。 然後在「昂貴」開始時檢查當前存儲的編號,如果它爲零,則從「昂貴」返回零而不執行昂貴的部分。

您也可以爲每位員工做到這一點,這將爲您節省大量時間,但不會成爲「全球」。