{ "cells": [ { "cell_type": "markdown", "id": "ab56029a", "metadata": {}, "source": [ "(interpretability)=\n", "\n", "# Компилируемость vs Интерпретируемость\n", "\n", "**Компилятор** — программа, переводящая текст, написанный на языке программирования, в набор машинных кодов.\n", "\n", "**Интерпретация** — построчный анализ, обработка и выполнение исходного кода программы или запроса.\n", "\n", "Источник - Wikipedia ([1](https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%82%D0%BE%D1%80) и [2](https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%82%D0%B5%D1%80%D0%BF%D1%80%D0%B5%D1%82%D0%B0%D1%82%D0%BE%D1%80)).\n", "\n", "## Компилятор `python`\n", "\n", "Компилируемых языков много. Ограничимся в рассмотрении `C/C++`. Цель компилятора `C/C++` --- преобразовать текст программы на языке программирования высокого уровня (`C/C++` в данном случае) и преобразовать его в машинный код. Большинство современных компиляторов (например, `gcc`) являются трехэтапными в соответствии с следующей структурой.\n", "\n", "```{figure} /_static/lecture_specific/interpretability/Compiler_design.png\n", ":scale: 50%\n", ":name: comp_design\n", "```\n", "\n", "- Первая часть (*front end*) просматривает файлы исходного кода (файлы `.cpp`, например), проводит проверку на синтаксис, проверку типов (`C/C++` статически типизированный язык) и т.п. Если обнаруживается ошибка, то генерируется ошибка компиляции. В ином случае на выходе получается внутреннее или промежуточное представление исходного кода. Это внутреннее представление обычно представляет из себя более низкоуровневый код, который уже не несёт в себе информации об исходном языке.\n", "\n", "- Вторая часть (*middle end*) производит такие оптимизации над промежуточным кодом, которые не зависят ни от архитектуры процессора под который компилируется исходный код, ни от языка программирования, на котором исходный код написан.\n", "\n", "- Третья часть (*back end*) транслирует промежуточное представление в машинный код для конкретной машины, попутно производя оптимизации, специфичные для архитектуры этой машины.\n", "\n", "\n", "Такая трехэтапная структура позволяет использовать один и тот же *middle end* для разных языков программирования и архитектур процессоров, меняя *front end* и *back end*.\n", "\n", "## Интерпретатор `C/C++`\n", "\n", "`Python` --- интерпретируемый язык программирования и установка `python` как раз и подразумевает установку интерпретатора. В большинстве случаев устанавливают стандартный написанный на языке `C` интерпретатор `CPython`. Существуют и альтернативные менее распространенные интерпретаторы для `python`, такие как [jython](https://www.jython.org/), [cython](https://cython.org/), [PyPy](https://www.pypy.org/) и др.\n", "\n", "Исходный код `python` не транслируется в машинный код непосредственно, а вместо этого транслируется в *байт код*, который исполняется *виртуальной машинной python*. При этом трансляция кода и его исполнение происходят одновременно, т.е. интерпретатору не требуется заранее увидеть исходный код всей программы, чтобы начать его исполнять. Говоря конкретнее, интерпретатор `python` исполняет команды в скрипте сверху вниз, не заглядывая вперёд.\n", "\n", "\n", "## Интерпретатор vs. компилятор\n", "\n", "1. **Требования к наличию транслятора**:\n", " - **компилятор** требуется только на этапе компиляции программы. Когда программа скомпилирована, она может полноценно функционировать без наличия самого компилятора.\n", " - **интерпретатор** требуется при каждом запуске программы. Без интерпретатора запустить программу не удастся.\n", "2. **Возможность оптимизации**:\n", " - Так как **компилятор** анализирует весь исходный код программы целиком, то он может оценить сценарии её работы и сгенерировать эффективный машинный код.\n", " - Так как **интерпретатор** видит код программы кусками, то он не может оценить возможные сценарии её работы и возможности оптимизации сводятся к минимуму. \n", "3. **Интерактивность**:\n", " - Так как **компилятор** требует весь исходный код программы целиком, то возможности интерактивного взаимодействия сильно ограничены.\n", " - Так как **интерпретатор** обрабатывает исходный код кусками, то открываются возможности к интерактивной подаче новых команд на лету.\n", "4. **Кроссплатформенность**:\n", " - **компилятор** старается оптимизировать генерируемый код с учетом особенностей операционной системы и архитектуры целевой платформы. В связи с этим требуется отдельная компиляция исходного кода, чтобы сгенерировать машинный код под машину с отличной архитектурой.\n", " - Исходный код на `python` запускается внутри виртуальной машины `python` (**интерпретатора**), которая изначально компилируется для работы на определенной платформе. За счет этого в подавляющем большинстве случаев программист может абстрагироваться от особенностей операционной системы и архитектуры целевой платформы." ] } ], "metadata": { "jupytext": { "text_representation": { "extension": ".md", "format_name": "myst" } }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" }, "source_map": [ 10 ] }, "nbformat": 4, "nbformat_minor": 5 }