Найти в Дзене
Заходи в Ай-Ти

Как устроен Python и почему он такой медленный (отличия python от других языков)

Оглавление

В сообществе программистов хорошо известно, что Python не выигрывает ни в одной гонке.

Но несмотря на это, Python великолепен, и он всем нравится.

Но он очень медленный...

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

Но сначала давайте усвоим некоторые основы языков программирования.

Уровни абстракции

Как вы, возможно, знаете, языки программирования часто характеризуются уровнем абстракции.

  • Низкий уровень абстракции указывает на то, что язык ближе к аппаратному (труден для интерпретации).
  • Высокий уровень показывает, что код ближе к пользователю (его легче интерпретировать).
Уровни абстракции
Уровни абстракции

C++, PHP, Java, Python… все они считаются современными (высокоуровневыми) языками программирования, поскольку они могут работать практически в любых системах.

На ассемблере вам нужно написать отдельную программу в соответствии с инструкциями каждого конкретного процессора (нельзя запускать один и тот же код на разных процессорах).

Например , если вы создаете программу, которая печатает «Hello world», и отправляете код своему другу (у которого другая модель компьютера), когда он попытается ее выполнить, она, вероятно, не запустится.

Современные языки — высший уровень абстракции

Современные языки с абстракцией
Современные языки с абстракцией

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

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

С другой стороны, другие языки упрощают задачи, позволяя работать с более читаемым и гибким кодом .

Это случай - Python. Его можно использовать практически для чего угодно, и его легко реализовать, но у него есть недостаток: он не так эффективен для определенных задач.

Но почему именно Python такой «медленный»?

Давайте пересмотрим некоторые особенности языка, чтобы ответить на этот вопрос.

## Интерпретируемый язык

Прежде всего, Python — это интерпретируемый язык , а это означает, что код читается и выполняется программой (называемой интерпретатором) построчно во время выполнения .

Это один из способов преобразования вашего кода в машинный код.

Компилируемые языки
Еще один способ сделать ваш код «понимаемым машиной» — это процесс компиляции.

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

Компилируемые и интерпретируемые языки
Компилируемые и интерпретируемые языки

# Почему интерпретируемые языки медленнее?
В интерпретируемых языках каждая строка исходного кода транслируется в машинный код «на лету» во время выполнения.

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

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

## CPython и его глобальная блокировка интерпретатора (GIL)

Стандартный интерпретатор Python — CPython. Он написан на C и Python и компилирует код Python в байт-код перед его интерпретацией .

Чтобы предотвратить одновременное выполнение байт-кодов Python несколькими собственными потоками, CPython использует глобальную блокировку интерпретатора.

Эта блокировка необходима, поскольку управление памятью CPython не является потокобезопасным .

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

Глобальный рабочий процесс блокировки переводчика
Глобальный рабочий процесс блокировки переводчика

Динамическая типизация

Кроме того, Python является динамически типизированным, а это означает, что вам не нужно объявлять тип переменной при ее инициализации.

Но как это влияет на эффективность?

Ну, в динамически типизированных языках типы определяются во время выполнения .

Это означает, что интерпретатору необходимо выполнять проверку типов каждый раз, когда он выполняет фрагмент кода .

Это требует дополнительной обработки для определения типа каждой переменной и того, как следует выполнять операции на основе этих типов.

А что является противоположностью динамически типизированных языков?

Статически типизированные языки!

В этом случае тип переменной известен во время компиляции, а не во время выполнения .

Как следствие, типы известны во время компиляции, и компиляторы могут лучше оптимизировать выполнение кода . Это приводит к более быстрым, но не таким гибким программам.

Некоторыми языками, использующими этот подход, являются C++ и Rust.

Статические и динамические типизированные языки
Статические и динамические типизированные языки

Сбор мусора

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

Python автоматически управляет выделением и освобождением памяти для своих объектов посредством сборки мусора.

Основным методом, который он использует для сборки мусора, является подсчет ссылок. Каждый объект в Python имеет счетчик ссылок , который представляет собой количество ссылок, указывающих на него.

Когда счетчик ссылок падает до нуля, то есть ссылок на объект не остается, он немедленно удаляется из памяти.

Рабочий процесс сборщика мусора
Рабочий процесс сборщика мусора

Однако вывоз мусора – палка о двух концах

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

Но это приводит к накладным расходам и непредсказуемости, которые могут повлиять на производительность приложения .

Заключение

В заключение отметим четыре основные особенности, которые делают Python медленным:

  • Интерпретируемое выполнение, которое добавляет уровень абстракции между кодом и машинным языком, замедляя выполнение по сравнению с скомпилированными языками.
  • Глобальная блокировка интерпретатора , которая не позволяет многопоточным программам полностью использовать многоядерные процессоры.
  • Динамическая типизация, определяющая тип объекта во время выполнения, что означает дополнительную работу интерпретатора во время выполнения.
  • И, наконец, сборка мусора , поскольку сбор неиспользуемых объектов может увеличить задержку выполнения программы, особенно при работе с большим количеством объектов или сложными структурами данных.

❤️ Если вам понравилась статья, ставьте лайк и подписывайтесь на мой канал "Заходи в Ай-Ти".

👍 Если у вас остались вопросы или есть интересные темы, которые вы хотите, чтобы я разобрал, то пишите в комментариях. Ваше мнение очень важно для меня!