我正在處理一個優化問題,該問題涉及在對象集合上最小化昂貴的地圖操作。火花短路,排序和懶惰地圖
天真溶液會是這樣的
rdd.map(expensive).min()
然而,映射函數將返回保證是值> = 0。因此,如果任何一個的結果是0,I可以採取作爲答案和不需要計算其餘的地圖操作。
是否有使用Spark做到這一點的慣用方式?
我正在處理一個優化問題,該問題涉及在對象集合上最小化昂貴的地圖操作。火花短路,排序和懶惰地圖
天真溶液會是這樣的
rdd.map(expensive).min()
然而,映射函數將返回保證是值> = 0。因此,如果任何一個的結果是0,I可以採取作爲答案和不需要計算其餘的地圖操作。
是否有使用Spark做到這一點的慣用方式?
是否有一種使用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?
如果「貴」是真的昂貴,也許你可以寫的「昂貴」,比方說,SQL的結果(或者提供給所有工人的任何其它存儲)。 然後在「昂貴」開始時檢查當前存儲的編號,如果它爲零,則從「昂貴」返回零而不執行昂貴的部分。
您也可以爲每位員工做到這一點,這將爲您節省大量時間,但不會成爲「全球」。