我想知道逐个执行一组操作而不是累积操作的性能成本是多少。 下面是一些代码来表示这两种方案:
场景 1:
val operations: List[Row => Boolean]
val rdd: RDD[Row]
val result: RDD[Boolean] = rdd.flatMap(row => operations.map(f => f(row)))
场景 2
val operations: List[Row => Boolean]
val rdd: RDD[Row]
val result: RDD[Boolean] = sc.union(operations.map(f => rdd.map(f)))
我知道第二个更贵,但我有一些理由喜欢它,我想知道它有多贵。
我的操作数量在 10 到 100 之间,RDD 大小以百万或更多为单位。
我认为最好的方法是对代表性数据执行并对结果进行基准测试。只有这样,你才能得到一个准确反映现实生活表现的答案。
虽然第一个可能受益于仅加载一次数据,但还有许多其他因素在起作用,例如:
- 世系的长度(数据缓存、洗牌(。
- 输入格式(如果从源重新执行世系(。
- 为每个操作和 GC 配置分配的内存量。
- 从单个传递操作生成的数据总量。
- 群集配置。
- 下游转换。
第一种情况可能导致 GC 暂停时间延长或与 GC 相关的 OOM、磁盘溢出增加或资源利用率低下。第二种方法可实现更高的粒度,尤其是在动态分配时。