首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >flatmap是否提供了比filter+map更好的性能?

flatmap是否提供了比filter+map更好的性能?
EN

Stack Overflow用户
提问于 2019-06-26 04:00:36
回答 2查看 777关注 0票数 6

我有一个相当大的数据集(100个million+记录和100个列),我正在用spark处理。我正在将数据读入spark数据集,并希望过滤此数据集并将其字段的子集映射到case类。

代码看起来有点类似,

代码语言:javascript
复制
case class Subset(name:String,age:Int)
case class Complete(name:String,field1:String,field2....,age:Int)

val ds = spark.read.format("csv").load("data.csv").as[Complete]

#approach 1
ds.filter(x=>x.age>25).map(x=> Subset(x.name,x.age))

#approach 2
ds.flatMap(x=>if(x.age>25) Seq(Subset(x.name,x.age)) else Seq.empty)

哪种方法更好?关于如何让这段代码更有性能,还有什么其他的建议吗?

谢谢!

编辑

我运行了一些测试来比较运行时,看起来方法2相当快,我用来获得运行时的代码如下所示,

代码语言:javascript
复制
val subset = spark.time {
   ds.filter(x=>x.age>25).map(x=> Subset(x.name,x.age))
}

spark.time {
   subset.count()
}

and 

val subset2 = spark.time {
   ds.flatMap(x=>if(x.age>25) Seq(Subset(x.name,x.age)) else Seq.empty)
}

spark.time {
   subset2.count()
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-26 17:00:00

更新:我最初的回答包含一个错误: Spark确实支持Seq作为flatMap的结果(并将结果转换回Dataset)。对于造成的混乱,我表示歉意。我还添加了有关提高分析性能的更多信息。

更新2:我没想到您使用的是Dataset而不是RDD (!)。这并不会对答案产生重大影响。

Spark是一个分布式系统,它将数据分区到多个节点上,并并行处理数据。就效率而言,导致重新分区(需要在节点之间传输数据)的操作在运行时的开销远远高于就地修改。此外,您应该注意到,仅转换数据的操作(如filtermapflatMap等)仅被存储,直到执行动作操作(如reducefoldaggregate等)时才会执行。因此,这两种选择实际上都没有起到任何作用。

当对这些转换的结果执行操作时,我认为filter操作的效率会高得多:它只处理传递谓词x=>x.age>25 (更典型地写为_.age > 25)的数据(使用后续的map操作)。虽然看起来filter创建了一个中间集合,但它的执行速度很慢。因此,Spark似乎将filtermap操作融合在一起。

坦率地说,你的flatMap操作很可怕。它强制每个数据项的处理、序列创建和随后的扁平化,这肯定会增加整体处理。

也就是说,提高分析性能的最佳方法是控制分区,以便在尽可能多的节点上大致平均地拆分数据。参考this guide作为一个很好的起点。

票数 5
EN

Stack Overflow用户

发布于 2019-06-26 05:01:56

从语法的逻辑判断,第一种方法应该使用较少的空间,因为flatMap扩展到.map().flatten,两者都使用相同大小的参数。它在Scala REPL中编译为相同的Java字节码(编辑:当使用一个特殊的示例时,这显然不能补偿用相当大的数据实际测试它)。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56761223

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档