[英]Why dataset.count() is faster than rdd.count()?
我创建了一个Spark Dataset[Long]
:
scala> val ds = spark.range(100000000)
ds: org.apache.spark.sql.Dataset[Long] = [id: bigint]
当我运行ds.count
它给我的结果是0.2s
(在4核8GB的计算机上)。 此外,它创建的DAG如下:
但是,当我运行ds.rdd.count
,结果为4s
(同一台机器)。 但是它创建的DAG如下:
因此,我的怀疑是:
ds.rdd.count
只创建一个阶段而ds.count
只创建两个阶段? ds.rdd.count
只有一个阶段时,为什么它比具有2个阶段的ds.count
慢? 为什么ds.rdd.count只创建一个阶段而ds.count只创建两个阶段?
这两个计数实际上都是两步操作。 区别在于,在ds.count
情况下,最终聚合是由执行者之一执行的,而ds.rdd.count
则在驱动程序上聚合最终的结果 ,因此该步骤未反映在DAG中:
另外,当
ds.rdd.count
只有一个阶段时,为什么它变慢
同上。 此外, ds.rdd.count
必须初始化(然后进行垃圾回收)1亿个Row
对象,这些对象几乎是免费的,并且可能占据了此处大部分时间差。
最后,除非谨慎使用,否则类似range
的对象不是一个好的基准测试工具。 取决于上下文,范围内的计数可以表示为恒定时间操作,即使没有显式优化也可以非常快(例如参见spark.sparkContext.range(0, 100000000).count
),但不能真实反映性能工作量。
相关信息: 如何知道哪个计数查询最快?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.