当读到spark和 DataFrame
(这是 Dataset[Row]
)以及 Dataset
,经常提到 Dataset
我们利用 Encoders
有效地将jvm对象转换为spark的内部数据表示。在scala中,有为case类和基元类型提供的隐式编码器。然而,也有一些问题 RowEncoder
我相信,它实现了 Row
在Dataframe中。
我的问题是
在jvm对象和spark的内部二进制表示之间的高效转换方面,有 DataFrame
s和 Dataset
在表演上是一样的吗?
与泛型相比,特定类型(如scala中的case类)提供了哪些额外的好处 Row
就编码(序列化/反序列化)而言?除了编译时类型安全之外,类型化jvm对象是否比半类型化(或“非类型化”)的jvm对象更有优势 Row
?
2条答案
按热度按时间nom7f22z1#
Dataframe只是带有spark row类编码器的数据集。所以在本质上,Dataframe是一个数据集。
编码器也不会发挥任何作用,除非你是使用非列函数(函数采取一个lambda像map,reduce,flatmap。)的时刻,你确实使用这些函数之一,将有一个性能的打击,因为你打破codegen催化剂是做两个部分,因为它不能优化lambda。这意味着您可能根本不想使用这些函数,并且可以完全忽略数据集/Dataframe的差异,因为如果不使用这些函数,就永远不会编码。
根据我的经验,使用数据集和类型api可以获得的类型安全的好处不值得对性能造成巨大的影响。在几乎所有的情况下,我发现您应该留在Dataframe中,并且只使用基于列的函数和udf来获得最佳性能。
另外要注意的是,在并行化集合时,只会使用编码器,所有数据源都会提供行或内部行来触发,因此编码器不会用于大多数源。
xxe27gdn2#
我建议你参考一下databrick的博客。他们很好地解释了何时使用dataframe、dataset和rddapi以及它们的性能比较。
此外,本次spark峰会还有助于您确定
why Dataset apis are slower than Dataframe in spark 2.0 and how they improved it in spark 2.2 by optimising whole-stage code generation