Чем компиляторы отличаются от интерпретаторов

Чем компиляторы отличаются от интерпретаторов

27 апреля 2022 г.

Готовитесь к собеседованию, экзамену или просто хотите узнать, что делают компиляторы и интерпретаторы? В самом простом смысле компилятор компилирует весь код целиком для последующего использования, тогда как интерпретатор считывает код построчно во время выполнения.


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


Ниже приведены темы, которые мы затронем, чтобы уладить дебаты компилятор против интерпретатора


Что такое компилятор


Историческое определение [компилятора] (https://en.wikipedia.org/wiki/Compiler) определяет его как программное обеспечение, которое преобразует исходный код компьютерной программы в машинные инструкции или машинный код. Исходный код — это код, который пишут разработчики, тогда как машинный код состоит из нулей и единиц и состоит из инструкций для ЦП компьютера по выполнению задач.


Приведенное выше определение по существу означает, что компилятор должен понимать механику языка программирования, на котором написан исходный код, и по этой причине компиляторы зависят от языка. Пример: один из компиляторов C — GCC, а компилятор байт-кода java — Javac.


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


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


Как работает компилятор


Также обратите внимание, что вывод в виде машинного кода/исполняемого файла не является на 100% универсальным, он включает в себя инструкции для конкретного процессора. Например, AMD может не понимать двоичный/машинный код, сгенерированный для процессоров Intel. Таким образом, компиляторы также должны быть специфичными для платформы.


А как насчет транспилятора…


В настоящее время термин «компилятор» также используется для обозначения многих других вариантов использования. Он также используется для программного обеспечения, которое переводит исходный код из одного формата в другой. Более подходящим термином для такого программного обеспечения является транспайлер, но все это размыто.


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


Возьмем пример компилятора Java, который переводит файлы «.Java» в файлы .class. Файл «.Class» — это не окончательный машинный код, это промежуточный байт-код, который нуждается в дальнейшей трансляции или интерпретации для машины. Но тем не менее, мы называем программное обеспечение, которое преобразует «.Java» в «.Class», компилятором.


Вы также можете найти альтернативный компилятор для Java, который переводит код Java в код C путем преобразования файлов Java в файлы языка C. Затем код языка C может быть скомпилирован компилятором C в машинный код. Многие назвали бы этот тип программного обеспечения конвертером исходного кода языка (транспилятором), а не компилятором.


Что такое интерпретатор?


Опять же, если мы посмотрим на историческое определение [интерпретатора] (https://en.wikipedia.org/wiki/Interpreter_(computing)), интерпретатор — это программа, которая считывает исходный код строка за строкой и генерирует машинные инструкции в время работы.


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


На приведенной ниже диаграмме показан упрощенный алгоритм работы интерпретатора.


Как работает интерпретатор


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


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


Подождите, а как насчет JIT (Just in Time Compiler)


Компилятор Just in Time — это еще один вариант компиляторов, с которыми вы сталкиваетесь в современном мире. JIT-компилятор обычно считывает предварительно скомпилированный байт-код, сгенерированный компилятором, и переводит его в машинный код, на лету, во время выполнения.


Давайте расширим наше понимание компилятора Java. Компилятор Java преобразует .java в .class. «.Class: содержит байт-код, который работает на виртуальной машине Java — JVM. Но какое это имеет отношение к JIT?


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


Почему JIT? Для повышения производительности исполнения!


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


Компилятор и интерпретатор: несколько примеров


Давайте посмотрим, как исходный код различных языков программирования в конечном итоге преобразуется в машинные инструкции —


Язык C (машинный код компилятором)

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


  • Предварительная обработка — расширение макросов и включение файлов. Кроме того, удалите комментарии и т. д., чтобы сгенерировать один чистый набор кода.

  • Компиляция — преобразование исходного кода в сборку

  • Сборка — преобразование ассемблерного кода в инструкции процессора.

  • Связывание – Соберите все модули заранее (статическое связывание) или во время выполнения (динамическое связывание).

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


Java (компилятор и интерпретатор JVM)

Очевидно, что Java — это двухэтапный процесс. Первым шагом является создание независимого от платформы байт-кода в виде файлов классов из java-файлов. Это то, что делает Java независимым от платформы языком с точки зрения разработчика, поскольку разработчикам просто нужно беспокоиться о создании стандартных файлов классов.



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


Вы можете прочитать об [онлайн-компиляторах Java] (https://noeticforce.com/online-java-compiler-and-editors)


Python (компилятор против интерпретатора)

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


Затем файлы .pyc интерпретируются PVM — виртуальной машиной Python во время выполнения, аналогично тому, как байт-код Java интерпретируется JVM.


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


Кроме того, в экосистеме Python также есть что-то под названием Jython, которое преобразует код .py в байт-код, который может работать на самой JVM вместо PVM. Кроме того, у него также есть IronPython, который позволяет запускать код Python в средах .Net.


Вы также можете прочитать:


  • [Конвертер Python в Javascript] (https://noeticforce.com/best-tools-to-convert-python-to-javascript-and-vice-versa)

  • [Компиляция Python с помощью C] (https://noeticforce.com/cython-vs-python-vs-pypy-vs-cpython-python-with-c-and-beyond)

Заключительные замечания


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


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


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


Также опубликовано здесь



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE