我有一个csv文件:(customerId,orderId,spend)。我使用两种方法计算每个客户的总支出:
方法1 :使用DataFrame和groupBy
val df = ss.read
.option("header", false)
.option("inferSchema", true)
.csv("data.csv")
df
.groupBy("_c0")
.sum("_c2")
.collect()
方法2 :使用RDD和reduceByKey
sc
.textFile("data.csv")
.map(parseLine)
.reduceByKey(_ + _)
.collect()
private def parseLine(line: String) = {
val fields = line.split(",")
(fields(0).toInt, fields(2).toFloat)
}
两种方法的结果是相同的。然而,方法2总是比方法1更快(2x)。
第一个问题:这是因为方法1正在使用groupBy吗?如果是这样,当我在笔记本电脑上运行时,怎么会发生这种情况。即只有1个节点,即没有洗牌成本?
这是我的火花会话配置
.master("local[*]")
第二个问题:如何在保留良好性能(如方法2)的同时修改方法1以使用DataFrame?
谢谢!
答案 0 :(得分:1)
您的第一个代码扫描数据两次:
inferchema
。如果没有任何进一步的信息,我会将执行速度降低到这个事实。还有其他差异,例如计算执行计划的成本。
特定内存配置(包括堆外内存的大小)可能会进一步影响性能。
如何修改方法1以使用DataFrame,同时保留良好的性能,如方法2?
为read
方法提供架构参数。
当我在笔记本电脑上运行时,怎么会发生这种情况。即只有1个节点,即没有洗牌成本?
由于本地通信,本地计算机上的随机播放成本可能会降低,但它仍然是一个完整的混乱,包括磁盘IO,而且它仍然很昂贵。
这是因为方法1正在使用groupBy
不。groupBy
与此无关。 Dataset.groupBy
不是RDD.groupBy(Key)
。