Чтобы сравнить производительность Spark при использовании Python и Scala, я создал одно и то же задание на обоих языках и сравнил время выполнения. Я ожидал, что обе работы займут примерно одинаковое количество времени, но работа с Python заняла только одно, а работа с 27min
Scala - 37min
почти на 40% дольше! Я реализовал ту же работу в Java, и это 37minutes
тоже заняло . Как это возможно, что Python намного быстрее?
Минимальный проверяемый пример:
Работа на Python:
# Configuration
conf = pyspark.SparkConf()
conf.set("spark.hadoop.fs.s3a.aws.credentials.provider", "org.apache.hadoop.fs.s3a.AnonymousAWSCredentialsProvider")
conf.set("spark.executor.instances", "4")
conf.set("spark.executor.cores", "8")
sc = pyspark.SparkContext(conf=conf)
# 960 Files from a public dataset in 2 batches
input_files = "s3a://commoncrawl/crawl-data/CC-MAIN-2019-35/segments/1566027312025.20/warc/CC-MAIN-20190817203056-20190817225056-00[0-5]*"
input_files2 = "s3a://commoncrawl/crawl-data/CC-MAIN-2019-35/segments/1566027312128.3/warc/CC-MAIN-20190817102624-20190817124624-00[0-3]*"
# Count occurances of a certain string
logData = sc.textFile(input_files)
logData2 = sc.textFile(input_files2)
a = logData.filter(lambda value: value.startswith('WARC-Type: response')).count()
b = logData2.filter(lambda value: value.startswith('WARC-Type: response')).count()
print(a, b)
Скала работа:
// Configuration
config.set("spark.executor.instances", "4")
config.set("spark.executor.cores", "8")
val sc = new SparkContext(config)
sc.setLogLevel("WARN")
sc.hadoopConfiguration.set("fs.s3a.aws.credentials.provider", "org.apache.hadoop.fs.s3a.AnonymousAWSCredentialsProvider")
// 960 Files from a public dataset in 2 batches
val input_files = "s3a://commoncrawl/crawl-data/CC-MAIN-2019-35/segments/1566027312025.20/warc/CC-MAIN-20190817203056-20190817225056-00[0-5]*"
val input_files2 = "s3a://commoncrawl/crawl-data/CC-MAIN-2019-35/segments/1566027312128.3/warc/CC-MAIN-20190817102624-20190817124624-00[0-3]*"
// Count occurances of a certain string
val logData1 = sc.textFile(input_files)
val logData2 = sc.textFile(input_files2)
val num1 = logData1.filter(line => line.startsWith("WARC-Type: response")).count()
val num2 = logData2.filter(line => line.startsWith("WARC-Type: response")).count()
println(s"Lines with a: $num1, Lines with b: $num2")
Просто глядя на код, они кажутся идентичными. Я посмотрел на группы DAG, и они не предоставили никакой информации (или, по крайней мере, у меня нет ноу-хау, чтобы придумать объяснения, основанные на них).
Я был бы очень признателен за любые указатели.
python
scala
apache-spark
pyspark
maestromusica
источник
источник
Ответы:
Ваше базовое предположение, что Scala или Java должны быть быстрее для этой конкретной задачи, просто неверно. Вы можете легко проверить это с минимальными локальными приложениями. Скала первая:
Питон один
Результаты (по 300 повторений в каждом, Python 3.7.6, Scala 2.11.12),
Posts.xml
полученные из дампа данных hermeneutics.stackexchange.com со смесью совпадающих и не совпадающих шаблонов:Как видите, Python не только систематически быстрее, но и более последовательный (более низкий спред).
Уберите сообщение - не верьте необоснованным FUD - языки могут быть быстрее или медленнее в определенных задачах или в определенных средах (например, здесь Scala может быть поражен запуском JVM и / или GC и / или JIT), но если вы заявляете например, «XYZ на X4 быстрее» или «XYZ медленнее, чем ZYX (..) Приблизительно в 10 раз медленнее», это обычно означает, что кто-то написал действительно плохой код для тестирования.
Редактировать :
Чтобы решить некоторые проблемы, поднятые в комментариях:
local_connect_and_auth
, и не более, чем с файлом, связанным с сокетом ). Опять же, настолько дешево, насколько это возможно, когда дело доходит до связи между процессами.Изменить 2 :
Поскольку jasper-m беспокоился о стоимости запуска, можно легко доказать, что Python по-прежнему имеет значительное преимущество над Scala, даже если размер ввода значительно увеличен.
Вот результаты для 2003360 строк / 5.6G (один и тот же вход, только дублированный несколько раз, 30 повторений), который превосходит все, что вы можете ожидать в одной задаче Spark.
Обратите внимание на непересекающиеся доверительные интервалы.
Изменить 3 :
Чтобы ответить на другой комментарий от Jasper-M:
Это просто неверно в данном конкретном случае:
DataFrame
) реализует брутто-функциональность изначально в Python, за исключением ввода, вывода и связи между узлами.источник
Задание Scala занимает больше времени, поскольку имеет неверную конфигурацию, и поэтому задания Python и Scala были предоставлены с неравными ресурсами.
В коде есть две ошибки:
sc.hadoopConfiguration
это неправильное место для установки любой конфигурации Spark. Это должно быть установлено вconfig
экземпляре, который вы передаетеnew SparkContext(config)
.[ДОБАВЛЕНО] Учитывая вышесказанное, я бы предложил изменить код задания Scala на
и перепроверьте это снова. Могу поспорить, что версия Scala будет в X раз быстрее.
источник