7

我一直在尝试不同的方法来过滤类型化的数据集。事实证明,性能可能完全不同。

该数据集是基于 33 列和 4226047 行的 1.6 GB 数据行创建的。DataSet 通过加载 csv 数据创建并映射到案例类。

val df = spark.read.csv(csvFile).as[FireIncident]

UnitId = 'B02' 上的过滤器应返回 47980 行。我测试了以下三种方法:1)使用类型列(本地主机上约 500 毫秒)

df.where($"UnitID" === "B02").count()

2)使用临时表和sql查询(〜与选项1相同)

df.createOrReplaceTempView("FireIncidentsSF")
spark.sql("SELECT * FROM FireIncidentsSF WHERE UnitID='B02'").count()

3)使用强类型类字段(14,987ms,即慢30倍)

df.filter(_.UnitID.orNull == "B02").count()

我用python API再次测试了一下,同样的数据集,时间为17046ms,与scala API option 3的性能相当。

df.filter(df['UnitID'] == 'B02').count()

有人可以阐明 3) 和 python API 的执行方式与前两个选项的不同吗?

4

2 回答 2

9

这是因为这里的第 3 步。

在前两个中,spark 不需要反序列化整个 Java/Scala 对象——它只查看一列并继续前进。

第三,由于您使用的是 lambda 函数,spark 无法判断您只需要一个字段,因此它将每行的所有 33 个字段从内存中拉出,以便您可以检查一个字段。

我不确定为什么第四个这么慢。似乎它的工作方式与第一个相同。

于 2017-06-08T22:43:58.617 回答
0

在运行 python 时,首先将您的代码加载到 JVM 上,进行解释,然后最终将其编译为字节码。使用 Scala API 时,Scala 原生在 JVM 上运行,因此您将整个加载 python 代码剪切到 JVM 部分。

于 2016-12-20T20:54:54.543 回答