我有两个序列A和B.我们想要生成一个布尔序列,其中A中的每个元素都有一个子序列,它出现在B中。例如:
a = ["abababab", "ccffccff", "123123", "56575656"]
b = ["ab", "55", "adfadf", "123", "5656"]
output = [True, False, True, True]
A和B不适合记忆。一种解决方案可能如下:
val a = sc.parallelize(List("abababab", "ccffccff", "123123", "56575656"))
val b = sc.parallelize(List("ab", "55", "adfadf", "123", "5656"))
a.cartesian(b)
.map({case (x,y) => (x, x contains y) })
.reduceByKey(_ || _).map(w => w._1 + "," + w._2).saveAsTextFile("./output.txt")
人们可以理解,不需要计算笛卡尔积,因为一旦我们找到符合我们条件的第一对序列,我们就可以停止搜索。以A
的第一个元素为例。如果我们从头开始迭代B
,则B
的第一个元素是子序列,因此输出为True
。在这种情况下,我们非常幸运,但总的来说,没有必要验证所有组合。
问题是:有没有其他方法可以优化这种计算?
答案 0 :(得分:2)
我认为简短的回答是“不”:)
我也认为将Spark与迭代进行比较并不公平。您必须记住,Spark适用于无法进行顺序处理的庞大数据集。它与许多不同机器上可能同时执行的数千个任务并行运行您的功能。这样做是为了确保即使A
的第一个元素与B
的 last 元素匹配,处理也会在合理的时间内完成。
相反,迭代或循环是一种比较当时两个元素的顺序操作。它非常适合小型数据集,但不适用于大型数据集,绝对不适用于分布式处理。