笛卡儿产品使用火花

时间:2017-07-27 11:28:51

标签: algorithm scala apache-spark bigdata

我有两个序列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。在这种情况下,我们非常幸运,但总的来说,没有必要验证所有组合。

问题是:有没有其他方法可以优化这种计算?

1 个答案:

答案 0 :(得分:2)

我认为简短的回答是“不”:)

我也认为将Spark与迭代进行比较并不公平。您必须记住,Spark适用于无法进行顺序处理的庞大数据集。它与许多不同机器上可能同时执行的数千个任务并行运行您的功能。这样做是为了确保即使A的第一个元素与B last 元素匹配,处理也会在合理的时间内完成。

相反,迭代或循环是一种比较当时两个元素的顺序操作。它非常适合小型数据集,但不适用于大型数据集,绝对不适用于分布式处理。