3

Я экспериментировал с различными способами фильтрации типизированного набора данных. Оказывается, производительность может быть совсем другой.Производительность фильтра Spark DataSet

Набор данных был создан на основе рядов данных объемом 1,6 ГБ с 33 столбцами и 4226047 строк. DataSet создается путем загрузки данных csv и сопоставления с классом case.

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, для того же набора данных, выбор времени 17,046 мс, сравнимые с выполнением API scala вариант 3.

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

Может кто-нибудь пролить некоторый свет на 3) и Python API выполняются по-разному из первых двух вариантов?

ответ

0

При запуске python то, что происходит, это то, что сначала ваш код загружается в JVM, интерпретируется, а затем его окончательно скомпилируется в байт-код. При использовании Scala API Scala изначально запускается на JVM, поэтому вы вырезаете весь код python загрузки в часть JVM.

+0

API-интерфейс API Python и Scala API с сильным типизированным полем класса имеют сопоставимые результаты. Знаете ли вы, почему опция 3) на 30 раз медленнее, чем 1) или 2)? – YPL

4

Это из-за шага 3 here.

В первых двух искры не нужно десериализовать весь объект Java/Scala - он просто смотрит на один столбец и движется дальше.

В-третьих, поскольку вы используете лямбда-функцию, искра не может сказать, что вам просто нужно одно поле, поэтому он вытягивает все 33 поля из памяти для каждой строки, так что вы можете проверить один поле.

Я не уверен, почему четвертый настолько медленный. Похоже, он будет работать так же, как и первый.

+0

Очень проницательный ответ. Что бы произошло, если вы написали в '' Dataset '' в java: '' datasetRdd.filter (r -> r. getAs ("event_type_id"). Equals ("LOG")) ''? –