Профилирование PySpark-кода: пример с приложением Apache Spark для Python-разработчика

Профилирование PySpark, отладка Spark-приложения, Apache Spark Для разработчиков примеры курсы обучение, Школа Больших Данных Учебный Центр Коммерсант

Что такое профилирование кода, зачем это нужно и как работают Python-профилировщики в приложениях Apache Spark. Пример профилирования PySpark-программы.

Что такое профилирование и почему это важно для PySpark-приложений

Будучи написанном на java и Scala, Apache Spark также поддерживает декларативные API-интерфейсы Python, которые позволяют разработчику писать и запускать код на этом более простом языке программирования. PySpark использует Spark в качестве движка исполнения заданий обработки данных, с помощью шлюза Py4J транслируя Python-код в JVM-объекты.

На стороне драйвера PySpark взаимодействует с драйвером JVM с помощью Py4J при создании/инициализации сеанса (pyspark.sql.SparkSession) или контекста (pyspark.SparkContext) Spark-приложения. На стороне исполнителя рабочие процессы Python выполняют и обрабатывают собственные функции или данные. Они не запускаются, если PySpark-приложение не требует взаимодействия между рабочими процессами Python и JVM, а запускаются в отложенном режиме, т.е. только при вызове действий, когда необходимо обрабатывать собственные функции или данные Python. Например, при обработке UDF-файлов pandas или API-интерфейсов PySpark RDD. Подробнее о разнице между действиями и преобразованиями в Apache Spark мы писали здесь.

Благодаря библиотеке Py4J программы Python, работающие в интерпретаторе Python, могут динамически получать доступ к объектам Java в JVM. Методы вызываются так, будто объекты Java находятся в интерпретаторе Python, а к коллекциям Java можно получить доступ через стандартные методы коллекций Python. Это позволяет разработчикам распределенных Spark-приложений использовать популярный и более простой, чем Java, язык программирования, однако из-за кросс-языковых и межплатформенных трансляций эффективность программного кода снижается.

В частности, в программе PySpark сложнее выявить узкие места производительности и применить пользовательские оптимизации. Чтобы устранить эту трудность, PySpark поддерживает различные инструменты профилирования на основе cProfile, одной из стандартных реализаций профилировщика Python.

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

Профилировщики PySpark позволяют узнать о количестве вызовов функций, общем времени ее выполнения, с указанием имени файла и номером строки в коде, чтобы быстрее выявить замкнутые циклы в Python-программе и улучшить ее производительность. Справедливости ради стоит отметить, что профилирование не избавит разработчика от необходимости выбирать наиболее эффективные алгоритмы и структуры данных.

Профилирование бывает динамическим и статическим. Динамическое является детерминированным, т.е. все события вызова функций , возврата их результатов и исключений отслеживаются. А для интервалов между этими событиями, в течение которых выполняется пользовательский код, устанавливаются точные периоды времени. Поскольку детерминированный профилировщик отслеживает все вызовы функций в приложении, он создает много выходных данных и имеет высокие накладные расходы. Эти накладные расходы неодинаковы, поскольку зависят от количества фактических вызовов функций, что приводит к неточным и искаженным результатам.

Статистическое профилирование  случайным образом выбирает эффективный указатель инструкции и определяет, на что тратится время. Этот метод имеет меньше накладных расходов, поскольку код не требует инструментирования, но не является полным. Чтобы снизить затраты на профилировщик, можно использовать статистическое профилирование и собирать показатели время от времени, создавая моментальный снимок состояния работающей программы через определенные промежутки времени. Каждый раз профилировщик записывает выборку из всего стека вызовов, от выполняющейся в данный момент функции до ее самого верхнего предка в иерархии вызовов.

Хотя статистический профилировщик не обеспечивает такой же уровень детализации, как детерминированный, он работает быстрее, фильтруя незначительные вызовы, которые не влияют на общую производительность программы. Накладные расходы статического профилировщика являются однородными и регулируемыми, а также не вносят лишних данных в отчет.

Тем не менее, при профилировании важно выполнять динамический анализ, выполняя код и собирая реальные данные, а не полагаться на статическую проверку кода. Поскольку динамический анализ часто требует повторного запуска ПО, рекомендуется начинать с небольшого объема данных, чтобы сократить время на ожидание результатов каждой итерации.

Вспомнив, что такое профилирование ПО и почему это важно для программ на PySpark, далее рассмотрим специальные профилировщики Python-кода в Apache Spark.

Python-профилировщики для Apache Spark

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

Python предоставляет две разные реализации одного и того же интерфейса профилирования:

  • cProfile – расширение C с разумными накладными расходами, что подходит для профилирования долго выполняющихся программ и рекомендуется для большинства пользователей;
  • profile — модуль на чистом Python, интерфейс которого имитируется cProfile, но который добавляет значительные накладные расходы к профилируемым программам. Хотя этот модуль позволяет расширить С-профилировщик с помощью Python.

Модули профилировщика предназначены для предоставления профиля выполнения данной программы, а не для целей сравнительного тестирования. Профилировщики вносят накладные расходы для кода Python, но не для функций на языке C. Поэтому код на языке C будет выполняться быстрее, чем аналогичный код на Python.

Профилировщики cProfile и profile обеспечивают  детерминированное профилирование программ Python. Профиль — это набор статистических данных, описывающих, как часто и как долго выполняются различные части программы. Эту статистику можно форматировать в отчеты через модуль pstats, а отчеты по профилям основаны на классе Stats. Аккумуляторы Spark, о которых мы писали здесь, играют важную роль при сборе профильных отчетов от рабочих процессов Python. Помимо анализа стандартных методов PySpark API, начиная с версии 3.3, в Spark есть профилировщики пользовательских функций (UDF).

Поскольку в Python во время выполнения активен интерпретатор, наличие инструментированного кода не требуется для выполнения детерминированного профилирования. Python автоматически предоставляет перехватчик (необязательный обратный вызов) для каждого события. Кроме того, интерпретируемая природа Python сама по себе добавляет много накладных расходов на выполнение. Поэтому расходы на детерминированное профилирование не существенны, зато это метод профилирования обеспечивает обширную статистику времени выполнения программы Python.

Помимо детерминированных профилировщиков profile, cProfile и line_profiler, в Python есть и статистические профилировщики, такие как perf, Pyinstrument и профилировщик Linux. А также для получения данных о времени выполнения программных функций можно использовать таймеры в модуле timeit стандартной библиотеки time или  сторонний пакет codetiming.

Статистику количества вызовов можно использовать для выявления ошибок в коде (неожиданное количество вызовов) и для выявления возможных точек встроенного расширения (большое количество вызовов). Внутреннюю статистику времени можно использовать для выявления «горячих петель», которые следует тщательно оптимизировать. Для выявления ошибок высокого уровня при выборе алгоритмов следует использовать совокупную временную статистику. Обработка совокупного времени позволяет напрямую сравнивать статистику рекурсивных реализаций алгоритмов с итеративными реализациями.

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

Поэтому профилировщик profile предоставляет средства калибровки. После калибровки профилировщика он будет более точным, но иногда будет выдавать отрицательные числа, когда количество вызовов исключительно мало. Профилировщик модуля profile вычитает константу из времени обработки каждого события, чтобы компенсировать накладные расходы на вызов функции времени и удаление результатов. По умолчанию эта константа равна 0.

Распределенная природа Apache Spark предполагает, что исполнители распределены по рабочим узлам кластера, что усложняет задачу, поскольку необходимо агрегировать профили. Кроме того, для каждого исполнителя создается рабочий процесс Python для выполнения UDF PySpark, что усложняет профилирование. Впрочем, профилировщик UDF, представленный в Spark 3.3, отлично справляется с этим и становится основным инструментом для профилирования рабочих процессов для приложений PySpark.

Профилировщик UDF помогает глубже понять выполнение, выявить узкие места в производительности и повысить общую производительность UDF-функции. Профилировщик UDF реализован на основе профилировщика на стороне исполнителя, разработанного для API PySpark RDD. Профилировщик UDF и профилировщик на стороне исполнителя работают на рабочих процессах Python. Они управляются конфигурацией spark.python.profile, которая по умолчанию установлена в false.

Чтобы использовать статистический профилировщик в Python, необходимо установить сторонний инструмент, например Pyinstrument или py-spy. Каждый из них имеет свой вариант использования. Например, Pyinstrument не может обрабатывать код, который выполняется в нескольких потоках, или вызывает функции, реализованные в модулях расширения C, таких как NumPy или pandas.

Начиная с версии Python 3.12, интерпретатор поддерживает Linux-профилировщик perf, который может получать доступ к аппаратным счетчикам производительности на некоторых компьютерных архитектурах. Это один из самых продвинутых и мощных существующих профилировщиков. Он может предоставить подробную информацию обо всем стеке, включая события оборудования, системные вызовы, библиотечный код и пр. Кроме того, его накладные расходы небольшие и регулируемые.

Профилировщик perf доступен только в Linux, поскольку он встроен в ядро ​​операционной системы. Чтобы использовать его, придется установить дополнительный системный пакет, чтобы получить сопутствующий инструмент командной строки для доступа к базовой подсистеме ядра. Использование perf требует понимания глубокой работы Python на уровне исходного кода, включая специальные флаги компилятора.

Практический пример

Приложения PySpark выполняются как независимые наборы процессов в кластере, координируемые объектом SparkContext в программе драйвера. Со стороны драйвера PySpark — это обычный процесс Python. Поэтому PySpark-программу можно профилировать как обычную программу Python. Чтобы посмотреть, как это работает, напишем простое PySpark-приложение, которое создает датафрейм и выполняет операцию записи, сохраняя данные в CSV-файл. Код приложения, написанного и запущенного в Google Colab, выглядит так. Сперва установим библиотеки и импортируем пакеты:

!pip install pyspark
!apt-get install openjdk-8-jdk-headless -qq > /dev/null
!pip install faker

#импорт модулей
from pyspark.sql import SparkSession
import pyspark
import sys
import os
import random
import cProfile
import pstats
from pyspark.sql import SparkSession
from io import StringIO

os.environ["JAVA_HOME"] = "/usr/lib/jvm/java-8-openjdk-amd64"

# Импорт модуля faker
from faker import Faker

Создадим директорию для сохранения CSV-файла:

!mkdir sp-us-files

Напишем Python-код приложения Apache Spark, которое генерирует случайные данные о клиентах с помощью библиотеки Faker и профилируем его с использованием профилировщика cProfile:

# Создаем профайлер
pr = cProfile.Profile()
pr.enable()

# Создаем объект SparkSession и устанавливаем имя приложения
spark = SparkSession.builder.appName("MySparkApp").getOrCreate()

with cProfile.Profile() as pr:
  # добавляем RU-провайдер для библиотеки Faker
  fake = Faker('ru_RU')
  fake.add_provider(Provider)

  # создаем пустой список для хранения данных
  data1 = []

  # генерируем фейковые данные и добавляем их в список
  for i in range(100):
      k= random.randint(0, 1)
      name = fake.name()
      data1.append((i, name, random.randint(18, 100), random.randint(0, 100),random.randint(0, 100)))

  #создаем датафрейм из списка
  df = spark.createDataFrame(data1, schema=['id', 'Client', 'age', 'income', 'debt'])
  df.show()
  df.write.format("csv").mode("overwrite").save("/content/sp-us-files")

# Отключаем профайлер
pr.disable()

# Создаем объект StringIO для записи статистики профилирования
s = StringIO()
ps = pstats.Stats(pr, stream=s).sort_stats('cumulative')
ps.print_stats()

# Получаем результаты из StringIO объекта
statistics = s.getvalue()

# Записываем статистику в текстовый файл
with open("profile_stat.txt", "w") as f:
    f.write(statistics)

# Закрываем SparkSession, чтобы освободить ресурсы
spark.stop()

Результаты профилирования представляют собой таблицу с информацией о времени выполнения функций программы.

Профилирование PySpark, отладка Spark-приложения
Профилирование PySpark

Содержимое файла с результатами профилирования выглядит так:

       87357 function calls (86844 primitive calls) in 2.152 seconds

 Ordered by: cumulative time

 ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     46    0.000    0.000    2.081    0.045 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1015(send_command)
     46    0.001    0.000    2.080    0.045 /usr/local/lib/python3.10/dist-packages/py4j/clientserver.py:499(send_command)
     46    0.000    0.000    2.074    0.045 {method 'readline' of '_io.BufferedReader' objects}
     46    0.000    0.000    2.074    0.045 /usr/lib/python3.10/socket.py:691(readinto)
     46    2.074    0.045    2.074    0.045 {method 'recv_into' of '_socket.socket' objects}
     27    0.000    0.000    2.068    0.077 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1313(__call__)
      1    0.000    0.000    1.306    1.306 /usr/local/lib/python3.10/dist-packages/pyspark/sql/dataframe.py:885(show)
      1    0.000    0.000    0.699    0.699 /usr/local/lib/python3.10/dist-packages/pyspark/sql/readwriter.py:1398(save)
      1    0.000    0.000    0.086    0.086 /usr/local/lib/python3.10/dist-packages/pyspark/sql/session.py:1235(createDataFrame)
      1    0.000    0.000    0.084    0.084 /usr/local/lib/python3.10/dist-packages/pyspark/sql/session.py:1447(_create_dataframe)
      1    0.000    0.000    0.045    0.045 /usr/local/lib/python3.10/dist-packages/faker/proxy.py:29(__init__)
      1    0.000    0.000    0.045    0.045 /usr/local/lib/python3.10/dist-packages/faker/factory.py:23(create)
      1    0.000    0.000    0.043    0.043 /usr/local/lib/python3.10/dist-packages/pyspark/sql/session.py:1081(_createFromLocal)
     25    0.000    0.000    0.041    0.002 /usr/local/lib/python3.10/dist-packages/faker/factory.py:66(_find_provider_class)
     18    0.000    0.000    0.038    0.002 /usr/local/lib/python3.10/dist-packages/faker/utils/loading.py:31(list_module)
      1    0.000    0.000    0.037    0.037 /usr/local/lib/python3.10/dist-packages/pyspark/sql/session.py:930(_inferSchemaFromList)
     18    0.000    0.000    0.037    0.002 /usr/local/lib/python3.10/dist-packages/faker/utils/loading.py:38(<listcomp>)
    588    0.001    0.000    0.037    0.000 /usr/lib/python3.10/pkgutil.py:110(iter_modules)
    588    0.003    0.000    0.035    0.000 /usr/lib/python3.10/pkgutil.py:144(_iter_file_finder_modules)
      2    0.000    0.000    0.019    0.010 /usr/local/lib/python3.10/dist-packages/pyspark/sql/session.py:621(_jconf)
      1    0.000    0.000    0.016    0.016 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:4909(_to_java_object_rdd)
   1763    0.006    0.000    0.016    0.000 /usr/lib/python3.10/inspect.py:801(getmodulename)
      8    0.000    0.000    0.014    0.002 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1708(__getattr__)
      1    0.000    0.000    0.010    0.010 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:5455(_jrdd)
      1    0.000    0.000    0.010    0.010 {built-in method _functools.reduce}
    605    0.009    0.000    0.009    0.000 {built-in method posix.listdir}
      1    0.000    0.000    0.007    0.007 /usr/local/lib/python3.10/dist-packages/pyspark/sql/dataframe.py:482(write)
      1    0.000    0.000    0.007    0.007 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:5262(_wrap_function)
      1    0.000    0.000    0.007    0.007 /usr/local/lib/python3.10/dist-packages/pyspark/sql/readwriter.py:961(__init__)
 594/99    0.002    0.000    0.006    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1744(_merge_type)
    100    0.000    0.000    0.006    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/person/__init__.py:201(name)
      1    0.000    0.000    0.005    0.005 /usr/local/lib/python3.10/dist-packages/pyspark/context.py:751(parallelize)
    605    0.001    0.000    0.005    0.000 /usr/lib/python3.10/genericpath.py:39(isdir)
     46    0.004    0.000    0.004    0.000 {method 'sendall' of '_socket.socket' objects}
      1    0.000    0.000    0.004    0.004 /usr/local/lib/python3.10/dist-packages/pyspark/context.py:827(_serialize_to_jvm)
    100    0.000    0.000    0.004    0.000 /usr/local/lib/python3.10/dist-packages/faker/generator.py:161(parse)
    100    0.000    0.000    0.004    0.000 {method 'sub' of 're.Pattern' objects}
    5/2    0.000    0.000    0.004    0.002 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1570(__call__)
    101    0.000    0.000    0.004    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/session.py:957(<genexpr>)
     26    0.001    0.000    0.004    0.000 /usr/local/lib/python3.10/dist-packages/faker/generator.py:32(add_provider)
   1763    0.003    0.000    0.004    0.000 /usr/lib/python3.10/inspect.py:805(<listcomp>)
    100    0.001    0.000    0.004    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1642(_infer_schema)
   1763    0.002    0.000    0.004    0.000 /usr/lib/python3.10/posixpath.py:140(basename)
    605    0.004    0.000    0.004    0.000 {built-in method posix.stat}
     99    0.001    0.000    0.004    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1787(<listcomp>)
    302    0.000    0.000    0.004    0.000 /usr/local/lib/python3.10/dist-packages/faker/generator.py:177(__format_token)
      1    0.000    0.000    0.004    0.004 /usr/local/lib/python3.10/dist-packages/pyspark/sql/utils.py:139(is_timestamp_ntz_preferred)
      1    0.000    0.000    0.003    0.003 /usr/local/lib/python3.10/dist-packages/pyspark/context.py:816(reader_func)
    402    0.000    0.000    0.003    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/__init__.py:535(random_element)
    402    0.001    0.000    0.003    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/__init__.py:412(random_elements)
      1    0.000    0.000    0.003    0.003 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:5248(_prepare_for_python_RDD)
    302    0.000    0.000    0.003    0.000 /usr/local/lib/python3.10/dist-packages/faker/generator.py:84(format)
  12865    0.002    0.000    0.002    0.000 {built-in method builtins.isinstance}
    199    0.001    0.000    0.002    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:787(__init__)
    5/2    0.000    0.000    0.002    0.001 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1552(_get_args)
    589    0.001    0.000    0.002    0.000 /usr/lib/python3.10/posixpath.py:71(join)
     43    0.000    0.000    0.002    0.000 /usr/lib/python3.10/importlib/__init__.py:108(import_module)
     27    0.000    0.000    0.002    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1275(_build_args)
    402    0.000    0.000    0.002    0.000 /usr/local/lib/python3.10/dist-packages/faker/utils/distribution.py:57(choices_distribution)
     43    0.000    0.000    0.002    0.000 <frozen importlib._bootstrap>:1038(_gcd_import)
     43    0.000    0.000    0.002    0.000 <frozen importlib._bootstrap>:1022(_find_and_load)
   8778    0.001    0.000    0.001    0.000 {method 'endswith' of 'str' objects}
     27    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1257(_get_args)
   2353    0.001    0.000    0.001    0.000 /usr/lib/python3.10/posixpath.py:41(_get_sep)
    400    0.000    0.000    0.001    0.000 /usr/lib/python3.10/random.py:366(randint)
      6    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1525(__getattr__)
     40    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/py4j/compat.py:113(hasattr2)
     32    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/errors/exceptions/captured.py:177(deco)
   9998    0.001    0.000    0.001    0.000 {built-in method builtins.len}
     32    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:305(get_return_value)
     40    0.000    0.000    0.001    0.000 /usr/lib/python3.10/inspect.py:1726(getattr_static)
    400    0.001    0.000    0.001    0.000 /usr/lib/python3.10/random.py:292(randrange)
      1    0.000    0.000    0.001    0.001 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:359(_pickled)
      1    0.000    0.000    0.001    0.001 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:1314(_reserialize)
     18    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/faker/utils/loading.py:10(get_path)
      1    0.000    0.000    0.001    0.001 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:720(map)
      3    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/serializers.py:457(dumps)
      1    0.000    0.000    0.001    0.001 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:844(mapPartitionsWithIndex)
    995    0.001    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:673(__init__)
     27    0.001    0.000    0.001    0.000 {built-in method builtins.dir}
      3    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:59(dumps)
      1    0.000    0.000    0.001    0.001 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:5417(__init__)
      1    0.000    0.000    0.001    0.001 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:5140(_is_barrier)
   1781    0.001    0.000    0.001    0.000 {method 'sort' of 'list' objects}
    500    0.001    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1544(_infer_type)
      3    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:630(dump)
      3    0.000    0.000    0.001    0.000 {function CloudPickler.dump at 0x7b12ec2da7a0}
   1618    0.001    0.000    0.001    0.000 {built-in method builtins.getattr}
    702    0.001    0.000    0.001    0.000 /usr/lib/python3.10/random.py:239(_randbelow_with_getrandbits)
     20    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_collections.py:516(can_convert)
    199    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:798(<listcomp>)
      1    0.000    0.000    0.001    0.001 /usr/local/lib/python3.10/dist-packages/py4j/java_collections.py:519(convert)
     21    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1336(__init__)
     18    0.000    0.000    0.001    0.000 /usr/lib/python3.10/pathlib.py:957(__new__)
     18    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:2549(<lambda>)
    302    0.000    0.000    0.001    0.000 /usr/lib/python3.10/random.py:375(choice)
   2609    0.001    0.000    0.001    0.000 {method 'startswith' of 'str' objects}
      1    0.000    0.000    0.001    0.001 /usr/local/lib/python3.10/dist-packages/pyspark/context.py:618(defaultParallelism)
     18    0.000    0.000    0.001    0.000 /usr/lib/python3.10/pathlib.py:589(_from_parts)
    199    0.000    0.000    0.001    0.000 {built-in method builtins.all}
      2    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_collections.py:507(convert)
     29    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:263(get_command_part)
    101    0.000    0.000    0.001    0.000 /usr/lib/python3.10/random.py:506(choices)
     18    0.000    0.000    0.001    0.000 /usr/lib/python3.10/pathlib.py:569(_parse_args)
     43    0.000    0.000    0.001    0.000 <frozen importlib._bootstrap>:169(__enter__)
    110    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:214(smart_decode)
     30    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:691(reducer_override)
      1    0.000    0.000    0.001    0.001 /usr/local/lib/python3.10/dist-packages/pyspark/sql/readwriter.py:1032(format)
    846    0.000    0.000    0.001    0.000 /usr/local/lib/python3.10/dist-packages/faker/generator.py:100(set_formatter)
     86    0.000    0.000    0.001    0.000 <frozen importlib._bootstrap>:179(_get_module_lock)
   1763    0.001    0.000    0.001    0.000 /usr/lib/python3.10/importlib/machinery.py:17(all_suffixes)
     19    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_collections.py:501(can_convert)
    570    0.000    0.000    0.000    0.000 <string>:1(<lambda>)
    995    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:713(needConversion)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_collections.py:81(__setitem__)
     18    0.000    0.000    0.000    0.000 /usr/lib/python3.10/pathlib.py:56(parse_parts)
    114    0.000    0.000    0.000    0.000 /usr/lib/python3.10/inspect.py:1712(_shadowed_dict)
     40    0.000    0.000    0.000    0.000 /usr/lib/python3.10/inspect.py:1696(_check_class)
   1194    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:794(<genexpr>)
     43    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:216(_lock_unlock_module)
     57    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/person/__init__.py:248(first_name_female)
     57    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/person/__init__.py:263(last_name_female)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/readwriter.py:971(mode)
   1763    0.000    0.000    0.000    0.000 {method 'rfind' of 'str' objects}
     57    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/person/ru_RU/__init__.py:1390(middle_name_female)
   2373    0.000    0.000    0.000    0.000 {built-in method posix.fspath}
     27    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1283(<listcomp>)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:661(NamedTemporaryFile)
358/356    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}
     46    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/clientserver.py:271(_get_connection)
      9    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:580(_function_reduce)
    995    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:149(__call__)
     43    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/person/__init__.py:238(first_name_male)
      1    0.000    0.000    0.000    0.000 {built-in method io.open}
     33    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1379(__getattr__)
     43    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/person/__init__.py:253(last_name_male)
    135    0.000    0.000    0.000    0.000 /usr/lib/python3.10/logging/__init__.py:1455(debug)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/serializers.py:224(dump_stream)
     14    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle.py:241(_should_pickle_by_reference)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:693(opener)
     43    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/person/ru_RU/__init__.py:1387(middle_name_male)
    101    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/proxy.py:106(__getattr__)
    851    0.000    0.000    0.000    0.000 {built-in method builtins.setattr}
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:382(_mkstemp_inner)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/serializers.py:145(dump_stream)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:344(__init__)
    305    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/proxy.py:91(__getattribute__)
    302    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/generator.py:90(get_formatter)
      5    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1579(<listcomp>)
   1414    0.000    0.000    0.000    0.000 {built-in method builtins.hasattr}
     86    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:100(acquire)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/serializers.py:156(_write_with_length)
     15    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle.py:278(_lookup_module_and_qualname)
   1182    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/session.py:1115(<listcomp>)
     86    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:198(cb)
    194    0.000    0.000    0.000    0.000 /usr/lib/python3.10/inspect.py:1684(_static_getmro)
      1    0.000    0.000    0.000    0.000 {built-in method posix.open}
     86    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:71(__init__)
    606    0.000    0.000    0.000    0.000 {built-in method __new__ of type object at 0x5cbb069639a0}
     40    0.000    0.000    0.000    0.000 /usr/lib/python3.10/inspect.py:1705(_is_type)
     86    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:125(release)
      1    0.000    0.000    0.000    0.000 {built-in method builtins.print}
     94    0.000    0.000    0.000    0.000 {method 'format' of 'str' objects}
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/ipykernel/iostream.py:384(write)
     12    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:248(is_python_proxy)
    100    0.000    0.000    0.000    0.000 /usr/lib/python3.10/random.py:540(<listcomp>)
     40    0.000    0.000    0.000    0.000 /usr/lib/python3.10/inspect.py:1687(_check_instance)
   1066    0.000    0.000    0.000    0.000 {method 'getrandbits' of '_random.Random' objects}
    495    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1754(new_name)
     46    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/clientserver.py:258(get_thread_connection)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:118(json)
     21    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/finalizer.py:35(add_finalizer)
     43    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:173(__exit__)
    933    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
     20    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_collections.py:489(can_convert)
    135    0.000    0.000    0.000    0.000 /usr/lib/python3.10/logging/__init__.py:1724(isEnabledFor)
     35    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1238(__init__)
    605    0.000    0.000    0.000    0.000 {built-in method _stat.S_ISDIR}
    594    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1786(<genexpr>)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:573(_dynamic_function_reduce)
    995    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:121(needConversion)
   1200    0.000    0.000    0.000    0.000 {built-in method _operator.index}
     46    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:380(is_fatal_error)
    162    0.000    0.000    0.000    0.000 {built-in method sys.intern}
   1073    0.000    0.000    0.000    0.000 {built-in method builtins.callable}
    199    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:793(<listcomp>)
      3    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/ipykernel/iostream.py:195(schedule)
     18    0.000    0.000    0.000    0.000 /usr/lib/python3.10/pathlib.py:621(__str__)
     18    0.000    0.000    0.000    0.000 /usr/lib/python3.10/functools.py:884(wrapper)
    200    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:887(__iter__)
     17    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:2432(can_convert)
     46    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:993(_give_back_connection)
      5    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:434(_class_reduce)
     46    0.000    0.000    0.000    0.000 {method '_checkReadable' of '_io._IOBase' objects}
    100    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1036(toInternal)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_collections.py:535(<lambda>)
     15    0.000    0.000    0.000    0.000 /usr/lib/python3.10/pickle.py:322(_getattribute)
    201    0.000    0.000    0.000    0.000 {built-in method builtins.any}
      1    0.000    0.000    0.000    0.000 {built-in method posix.unlink}
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_collections.py:261(__init__)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/json/__init__.py:183(dumps)
    402    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/generator.py:60(random)
    702    0.000    0.000    0.000    0.000 {method 'bit_length' of 'int' objects}
     21    0.000    0.000    0.000    0.000 /usr/lib/python3.10/abc.py:117(__instancecheck__)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:139(_function_getstate)
     18    0.000    0.000    0.000    0.000 /usr/lib/python3.10/pathlib.py:865(parent)
     20    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:2494(can_convert)
     18    0.000    0.000    0.000    0.000 /usr/lib/python3.10/functools.py:818(dispatch)
    302    0.000    0.000    0.000    0.000 {method 'groups' of 're.Match' objects}
     18    0.000    0.000    0.000    0.000 /usr/lib/python3.10/pathlib.py:239(splitroot)
     99    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1793(<listcomp>)
     39    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:637(is_magic_member)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/json/encoder.py:182(encode)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/serializers.py:600(write_int)
      3    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1364(_detach)
     32    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:373(is_error)
     43    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:968(_sanity_check)
     17    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:2465(can_convert)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_collections.py:532(<lambda>)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/json/encoder.py:204(iterencode)
      3    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/serializers.py:204(_batched)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:921(jsonValue)
     14    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle.py:181(_is_registered_pickle_by_value)
    100    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1855(convert_struct)
      3    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:643(_garbage_collect_object)
      9    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:177(escape_new_line)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_collections.py:74(__init__)
      3    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/zmq/sugar/socket.py:543(send)
     21    0.000    0.000    0.000    0.000 {built-in method _abc._abc_instancecheck}
     11    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1475(__init__)
     26    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/__init__.py:284(__init__)
     38    0.000    0.000    0.000    0.000 {method 'split' of 'str' objects}
     46    0.000    0.000    0.000    0.000 /usr/lib/python3.10/socket.py:730(readable)
      1    0.000    0.000    0.000    0.000 {built-in method builtins.next}
    172    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}
     16    0.000    0.000    0.000    0.000 /usr/lib/python3.10/collections/__init__.py:980(__getitem__)
    6/1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1830(_create_converter)
     18    0.000    0.000    0.000    0.000 /usr/lib/python3.10/pathlib.py:608(_format_parsed_parts)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:597(_function_getnewargs)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:612(__getattr__)
     18    0.000    0.000    0.000    0.000 /usr/lib/python3.10/pkgutil.py:407(get_importer)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:235(encode_bytearray)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:292(__next__)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:167(<lambda>)
     34    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/compat.py:95(isbytearray)
     46    0.000    0.000    0.000    0.000 {method 'remove' of 'collections.deque' objects}
    172    0.000    0.000    0.000    0.000 {built-in method _thread.get_ident}
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:922(<listcomp>)
    172    0.000    0.000    0.000    0.000 {built-in method _imp.acquire_lock}
     47    0.000    0.000    0.000    0.000 {method 'encode' of 'str' objects}
      4    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:620(func_wrapper)
     43    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:165(__init__)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:193(unescape_new_line)
     46    0.000    0.000    0.000    0.000 {method '_checkClosed' of '_io._IOBase' objects}
     18    0.000    0.000    0.000    0.000 /usr/lib/python3.10/weakref.py:415(__getitem__)
    200    0.000    0.000    0.000    0.000 {built-in method builtins.iter}
    100    0.000    0.000    0.000    0.000 {built-in method _bisect.bisect_right}
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:644(close)
      4    0.000    0.000    0.000    0.000 {method 'write' of '_io.BufferedRandom' objects}
    6/1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1698(_has_nulltype)
    172    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.lock' objects}
      2    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:578(close)
      3    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:644(__init__)
    172    0.000    0.000    0.000    0.000 {built-in method _imp.release_lock}
      3    0.000    0.000    0.000    0.000 /usr/lib/python3.10/threading.py:1169(is_alive)
      5    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:696(jsonValue)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle.py:903(_typevar_reduce)
     17    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:2409(can_convert)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/utils.py:156(is_remote)
      6    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1701(<genexpr>)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/dataframe.py:132(__init__)
      1    0.000    0.000    0.000    0.000 {method 'close' of '_io.BufferedRandom' objects}
     46    0.000    0.000    0.000    0.000 {method 'strip' of 'str' objects}
     15    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle.py:195(_whichmodule)
     32    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/compat.py:92(ispython3bytestr)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle.py:318(_extract_code_globals)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/posixpath.py:377(abspath)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:253(_sanitize_params)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/ipykernel/iostream.py:321(_schedule_flush)
     18    0.000    0.000    0.000    0.000 /usr/lib/python3.10/pathlib.py:600(_from_parsed_parts)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/base64.py:90(standard_b64encode)
      2    0.000    0.000    0.000    0.000 /usr/lib/python3.10/typing.py:1096(__reduce__)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/_collections_abc.py:828(__contains__)
    108    0.000    0.000    0.000    0.000 {method 'random' of '_random.Random' objects}
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:224(_infer_return_type)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:205(<genexpr>)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/functools.py:35(update_wrapper)
     49    0.000    0.000    0.000    0.000 {method 'append' of 'collections.deque' objects}
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/base64.py:51(b64encode)
      2    0.000    0.000    0.000    0.000 /usr/lib/python3.10/weakref.py:452(get)
    100    0.000    0.000    0.000    0.000 {built-in method math.isfinite}
     17    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:2418(can_convert)
     17    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:2451(can_convert)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:245(_code_reduce)
    101    0.000    0.000    0.000    0.000 {method 'values' of 'collections.OrderedDict' objects}
     99    0.000    0.000    0.000    0.000 /usr/lib/python3.10/typing.py:1737(cast)
      3    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/finalizer.py:45(remove_finalizer)
      3    0.000    0.000    0.000    0.000 /usr/lib/python3.10/threading.py:1102(_wait_for_tstate_lock)
      3    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:430(get_method)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/generator.py:27(__init__)
      6    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:108(typeName)
      5    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:115(jsonValue)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/os.py:675(__getitem__)
     33    0.000    0.000    0.000    0.000 {method 'rsplit' of 'str' objects}
      4    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:161(<lambda>)
     11    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1817(_need_converter)
     26    0.000    0.000    0.000    0.000 {method 'insert' of 'list' objects}
      3    0.000    0.000    0.000    0.000 /usr/lib/python3.10/typing.py:306(inner)
     24    0.000    0.000    0.000    0.000 {method '__exit__' of '_thread.RLock' objects}
     18    0.000    0.000    0.000    0.000 {method 'lstrip' of 'str' objects}
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/cProfile.py:118(__exit__)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1852(<listcomp>)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/posixpath.py:338(normpath)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/random.py:519(<listcomp>)
      1    0.000    0.000    0.000    0.000 {built-in method binascii.b2a_base64}
     29    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/locale.py:396(normalize)
     35    0.000    0.000    0.000    0.000 {built-in method builtins.issubclass}
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/ipykernel/iostream.py:308(_is_master_process)
      3    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/clientserver.py:230(garbage_collect_object)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:281(rng)
    100    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/session.py:1479(prepare)
      6    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1853(<genexpr>)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:606(__init__)
     11    0.000    0.000    0.000    0.000 {method 'lower' of 'str' objects}
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:381(_module_reduce)
      3    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/ipykernel/iostream.py:91(_event_pipe)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/person/__init__.py:283(prefix_male)
     12    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py:1367(_get_object_id)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/broadcast.py:363(clear)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/providers/person/__init__.py:293(prefix_female)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle.py:345(_find_imported_submodules)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:625(<genexpr>)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/serializers.py:266(__init__)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/rdd.py:5257(<listcomp>)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:164(<lambda>)
      3    0.000    0.000    0.000    0.000 {built-in method posix.getpid}
      9    0.000    0.000    0.000    0.000 /usr/lib/python3.10/collections/__init__.py:977(__missing__)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/serializers.py:200(__init__)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:307(_cell_reduce)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/serializers.py:128(__ne__)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/posixpath.py:60(isabs)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/json/encoder.py:104(__init__)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/compat.py:101(bytetostr)
      3    0.000    0.000    0.000    0.000 {method 'acquire' of '_thread.lock' objects}
      2    0.000    0.000    0.000    0.000 {built-in method _struct.pack}
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/functools.py:65(wraps)
     18    0.000    0.000    0.000    0.000 {method 'reverse' of 'list' objects}
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/broadcast.py:356(__iter__)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/os.py:755(encode)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/proxy.py:284(__init__)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/session.py:1394(<listcomp>)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:588(__del__)
      2    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle_fast.py:158(<dictcomp>)
      3    0.000    0.000    0.000    0.000 {method '__exit__' of '_io._IOBase' objects}
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/serializers.py:125(__eq__)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle.py:668(_get_cell_contents)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:162(<lambda>)
      3    0.000    0.000    0.000    0.000 {method 'pop' of 'dict' objects}
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:563(__init__)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/cloudpickle/cloudpickle.py:772(_make_empty_cell)
      2    0.000    0.000    0.000    0.000 {method 'setdefault' of 'dict' objects}
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/readwriter.py:1111(options)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/typing.py:1161(__reduce__)
      3    0.000    0.000    0.000    0.000 {method 'getvalue' of '_io.BytesIO' objects}
      8    0.000    0.000    0.000    0.000 {built-in method math.floor}
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/dataframe.py:176(sparkSession)
      3    0.000    0.000    0.000    0.000 /usr/lib/python3.10/threading.py:553(is_set)
      1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
      1    0.000    0.000    0.000    0.000 {built-in method builtins.min}
      3    0.000    0.000    0.000    0.000 {method 'appendleft' of 'collections.deque' objects}
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/faker/proxy.py:339(__init__)
      1    0.000    0.000    0.000    0.000 /usr/lib/python3.10/tempfile.py:368(_get_candidate_names)
      2    0.000    0.000    0.000    0.000 {built-in method builtins.id}
      2    0.000    0.000    0.000    0.000 {method 'values' of 'dict' objects}
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/compat.py:89(isbytestr)
      1    0.000    0.000    0.000    0.000 {method 'keys' of 'dict' objects}
      2    0.000    0.000    0.000    0.000 {built-in method builtins.globals}
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/pyspark/sql/types.py:1851(<listcomp>)
      1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.10/dist-packages/py4j/protocol.py:160(<lambda>)
      2    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}
      1    0.000    0.000    0.000    0.000 {method 'clear' of 'set' objects}
      1    0.000    0.000    0.000    0.000 {built-in method builtins.max}
      1    0.000    0.000    0.000    0.000 {method 'update' of 'dict' objects}
      1    0.000    0.000    0.000    0.000 {built-in method sys.audit}

Содержимое этого файла показывает:

  • ncalls — количество вызовов;
  • tottime — общее время функции без учета времени, потраченного на вызовы подфункций;
  • percall – время на вызов, частное от деления tottime на ncalls;
  • cumtime – совокупное время, затраченное на эту и все подфункции (от вызова до выхода), точно даже для рекурсивных функций;
  • percall — частное от деления cumtime на примитивные вызовы;
  • filename:lineno(function) – имя файла и номер строки в нем с вызовом функции.

Если в первом столбце ncalls находятся два числа, например 3/1, это означает, что функция рекурсивная. Второе значение — это количество примитивных вызовов, а первое — общее количество вызовов. Когда функция не рекурсивна, эти два значения одинаковы, и печатается только одна цифра.

Результат профилирования показал, что наибольшее время (максимальное значение показателя cumtime) занимают метод send_command из файла /usr/local/lib/python3.10/dist-packages/py4j/java_gateway.py. Этот метод используется для отправки команд JVM через соединение, которое шлюз Py4J устанавливает между Python и JVM.

Узнайте больше про возможности Apache Spark для разработки приложений аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:

Я даю свое согласие на обработку персональных данных и соглашаюсь с политикой конфиденциальности.

Источники

  1. https://www.databricks.com/blog/2022/10/06/how-profile-pyspark.html
  2. https://www.javatpoint.com/pyspark-profiler
  3. https://spark.apache.org/docs/latest/api/python/development/debugging.html
  4. https://docs.python.org/3/library/profile.html
  5. https://realpython.com/python-profiling/
Поиск по сайту