что значит скомпилировать код

Что значит скомпилировать код

Синтаксис команды компиляции имеет вид:

компилятор [опции] файлы [библиотеки]

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

На UNIX-подобных системах имеется множество компиляторов. Большая часть из них является коммерческими продуктами. Для систем Linux пакет GCC является неотъемлемой частью дистрибутивов, поскольку является базовым компилятором сборки ядра системы и всех ее утилит.

Пакет компиляторов GCC

В него входят компиляторы:

Помимо этого, на Linux кластерах, являющихся сегодня основным видом высокопроизводительных вычислительных систем, широко используется пакет компиляторов Intel Compiler, наилучшим образом оптимизированный под платформу x86-64, являющуюся основной при построении вычислительных кластеров. Это коммерческй продукты и он приобретен Вычислительным центром СПбГУ.

Пакет компиляторов Intel

Рассмотрим подробнее работу с компилятором gcc.

Создадим файл с именем ex1.c с помощью команды touch. Откроем его в текстовом редакторе и наберем текст программы на языке С.

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

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

На терминал будет напечатана строка «Hello word».

Для того чтобы поменять имя создаваемого файла c a.out на любое другое необходимо использовать опцию -o:

В результате будет создан исполнимый файл с именем ex1.

Приведем несколько важных опций компилятора gcc (они справедливы и для icc)

Рассмотрим назначение опций более подробно на примерах.

В программах часто используются уже написанные ранее функции. Например, в приведенной выше программе, применялась системная функция вывода информации в стандартный поток printf. Для того чтобы транслятор на этапе создания программы, мог правильно обработать внешнюю функцию необходимо ее предварительно описать, либо внутри программы, либо в специальном заголовочном файле. Такие файлы еще называют include файлами, в языке С они подключаются с помощью специальной директивы #include. На первом этапе трансляции программы, запускается так называемый препроцессор, он находит файл с именем stdio.h, и вставляет его содержимое внутрь программы. Пути поиска задаются с помощью опции

Если используется стандартный заголовочный файл, то опцию -I для его поиска в командной строке компиляции программы указывать необязательно. Существует специальный каталог, где располагаются стандартные заголовочные файлы. Препроцессор автоматически просматривает его при поиске заголовочных файлов. Все сказанное в полной мере относится и к компилятору с языка Фортран. Отличие состоит в синтаксисе подключения include файла:

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

Попробуем скомпилировать программу командой:

В результате получим следующие сообщение об ошибке:

/tmp/ccgSk9AB.o(.text+0x49): In function `main’:
ex2.c: undefined reference to `pow’
collect2: ld returned 1 exit status

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

В результате будет создана программа с именем ex2, которая при запуске напечатает:

Подключение библиотеки было выполнено с помощью опции -lm. Файл этой библиотеки находится в каталоге /usr/lib. Полное его название libm, имена файлов библиотек подпрограмм всегда начинаются с префикса lib, за которым идет название библиотеки. При подключении библиотеки к программе в строке компилятора префикс lib заменяется на -l. Таким образом, подключение библиотеки libm осуществляется опцией -lm. Поскольку библиотека стандартная, находится в специальном каталоге, то нет необходимости указывать путь поиска файла библиотеки математических подпрограмм с помощью опции -L. Компилятор сам найдет его в директории /usr/lib. Работа с библиотеками имеет ряд аспектов, которые нуждаются в более подробном рассмотрении.

Динамические библиотеки, называемые также библиотеками общего пользования или разделяемыми библиотеками (shared library), загружаются на этапе выполнения программы. Код вызываемых функций не встраивается внутрь исполняемой программы, а вызывается по мере необходимости при запуске программы на исполнение. Такой подход позволяет создавать программы значительно меньшего объема. Динамические библиотеки хранятся обычно в определенном месте и имеют стандартное расширение. В ОС Windows файлы библиотек общего пользования имеют расширение .dll, а в UNIX-подобных системах .so. Если на этапе загрузки программы система не смогла найти необходимый код, то программа не запустится. Будет выдано сообщение об ошибке:

error while loading shared libraries: libxxx.so: cannot open shared object file: No such file or directory

Статические библиотеки в виде пакетов объектных файлов, присоединяются (линкуются) к исполнимой программе на этапе компиляции (в Windows такие файлы имеют расширение .lib, а в UNIX-подобных .a). В результате этого программа включает в себя все необходимы функции, что делает её автономной, хорошо переносимой, но увеличивает размер.

Статическая библиотека создается специальной командой:

ar rc libимя.a список_объектных_файлов

Объектные файлы создаются компиляцией функций с опцией -c. Рекомендуется каждую функцию (или подпрограмму в Фортране) оформлять в отдельном файле.

Динамическая библиотека создаются компилятором:

Для создания исполнимого файла со статической библиотекой потребуется команда:

Мы создали две версии программы: с использованием динамической и статической библиотек. Во втором случае использовалась опция -static, чтобы компилятор использовал статическую библиотеку libmy.a. Если бы динамической версии библиотеки не было, то эту опцию можно было бы не указывать. Компилятор, не найдя динамической библиотеки автоматически подключает статическую библиотеку. Опция -I

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

При запуске на исполнение разные версии программы, скорее всего, поведут себя по-разному:

Дело в том, что в момент загрузки программы, система ищет необходимые для запуска программы разделяемые библиотеки, чтобы собрать исполнимую программу. Поиск идет по заранее установленному списку директорий. Имена директорий перечислены в системном файле /etc/ld.so.conf. Очевидно, что в этот файл невозможно занести все индивидуальные каталоги пользователей. В этой ситуации на помощь приходят переменные окружения. Как уже говорилось ранее, в UNIX системах существует специальная переменная LD_LIBRARY_PATH, в которой каждый пользователь может перечислить директории для поиска разделяемых библиотек. Добавим к переменной LD_LIBRARY_PATH путь к директории lib, где находится библиотека libmy.so. Делается это командой

Читайте также:  что значит смайл демон с улыбкой

Данной командой мы к ранее установленному значению добавили путь к персональному каталогу пользователя с библиотечными файлами. Если теперь запустить программу
./prog_shared
то она сработает корректно.

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

Источник

Unix как IDE: Компиляция

Под Unix существует множество компиляторов и интерпретаторов, но здесь мы будем обсуждать лишь gcc как средство компиляции C-кода, и коротко коснемся использования perl в качестве примера интерпретатора.

GCC — это набор компиляторов, обладающий очень почтенным возрастом и распространяемый под лицензией GPL. Он известен как инструмент работы с программами на C и C++. Свободная лицензия и повсеместная распространенность на Unix-подобных системах стали залогом его неизменной популярности, хотя есть и более современные альтернативы, использующие инфраструктуру LLVM, такие как Clang.

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

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

Компиляция и сборка объектного кода

Объектный код компилируется вот такой командой:

Если код верен, будет создан нелинкованный двоичный объектный файл под именем example.o в текущей папке, или выведены сообщения о проблемах. Заглянуть внутрь полученного файла и увидеть его содержимое на языке ассемблера можно так:

Как вариант, можно попросить gcc сразу показать итоговый ассемблерный код при помощи параметра -S:

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

Препроцессор

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

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

Связывание объектов

Один или несколько объектных файлов могут быть связаны в соответствующий исполняемый файл:

Компиляция, сборка и связывание

Все вышеперечисленное может быть выполнено в один шаг при помощи команды:

Этот способ проще, но компиляция объектов по отдельности дает некоторый выигрыш в производительности: не нужно компилировать не изменявшийся код, но об этом мы поговорим в следующей статье.

Включение внешних файлов и связывание

Файлы C и заголовочные файлы могу быть явно включены в компиляцию при помощи параметра -l:

Аналогично, если код нужно динамически связать с уже скомпилированной системной библиотекой, доступной в одной из системных папок ( /lib или /usr/lib ), например, ncurses, этого можно добиться использованием ключа -l:

Если в процессе компиляции внешних связей много, имеет смысл внести их в переменные окружения:

Кстати, Makefile затем и создан, чтобы избавить нас от беспокойства о таких мелочах.

План компиляции

Чтобы посмотреть подробности внутренней кухни gcc, можно добавить ключ -v, и план компиляции будет выведен в стандартный поток вывода ошибок:

Если нет нужды генерировать объектные или исполняемые файлы, то для аккуратности можно использовать -###:

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

Расширенный вывод сообщений об ошибках

Существует возможность добавить ключи -Wall и/или -pedantic, чтобы gcc предупреждал нас о случаях, которые не обязательно являются ошибками, но могут ими быть:

Удобно включать такие опции в Makefile или в определении makeprg для Vim, так как они отлично сочетаются с окном quickfix, и помогают писать читабельный, совместимый и безошибочный код.

Профилирование процесса компиляции

Вы можете включить опцию -time, чтобы gcc отображал в тексте вывода время выполения каждого из шагов:

Оптимизация

Подобно любой команде Bash, все это можно вызывать прямо из Vim:

Интерпретаторы

Подход к интерпретируемому коду в Unix-системах иной. В своих примерах я буду использовать Perl, но те же принципы применимы для кода, например, на Python или Ruby.

Inline-код

Можно строку Perl-кода прямо на исполнение интерпретатору любым из перечисленных ниже способов Первый, наверное, самый простой и общеупотребительный способ работы с Perl; второй использует синтаксис heredoc, а третий — это классический конвейер Unix.

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

Можно проверить синтаксис кода без его выполнения с помощью ключа -c:

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

Скрипту после этого можно ставить атрибут исполняемого файла вызовом chmod. Также хорошим тоном считается переименовать файл, убрав расширения, поскольку он теперь считается почти настоящим исполняемым файлом:

Затем файл можно вызывать напрямую, без указания интерпретатора:

Вся эта кухня так здорово работает, что многие стандартные утилиты Linux-систем, такие как adduser, в действительности являются скриптами на Perl или Python.

В следующей публикации я расскажу о методах работы с make для сборки проектов, сравнимых с привычными IDE.

Источник

Как работает процессор и языки программирования

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

Все описанное ниже как всегда упрощено для лучшего понимания.

Процессор и оперативная память

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

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

Читайте также:  что делать если скорую жду более 2 часов

Процессор знает много команд и у каждой из них есть свой числовой код, например:

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

Понимаете прикол? Это значит, что вам нужно писать код для каждой архитектуры процессора. Жуть.

Так. Понятно. Процессор может выполнять маленькие числовые команды. Но откуда он их берет? Из оперативной памяти. Думайте об оперативке, как о большом количестве маленьких ячеек. Каждая ячейка имеет свой адрес — это обычное число, например 2001. По адресу ячейки процессор может запросить данные и оперативная память вернет их ему. Также в эту ячейку процессор может записать новые данные.

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

Получается такая картина: процессор обращается к оперативной памяти по адресу ячейки, оперативка возвращает ему команду из этой ячейки, процессор выполняет команду. А что дальше? А дальше процессор опять обращается к памяти (уже в другую ячейку), получает команду, выполняет ее и этот цикл повторяется снова и снова. То есть процессор все время выполняет какую-то заданную последовательность команд (числовых кодов). Эта последовательность команд называется машинным кодом.

Ассемблер

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

Для того, чтобы заставить процессор выполнить какую-то программу, например решить уравнение 2 + 2 * 2, нам нужно написать цепочку простых числовых команд.

Согласитесь, что писать такой код очень сложно и легко запутаться. И это мы всего лишь написали код для решения простого уравнения. А теперь представьте, как написать ВКонтактик или Инстаграм.

Для упрощения жизни люди придумали инструмент Ассемблер и язык программирования на ассемблере.

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

Помните примеры кодов команд, которые были указаны выше? Теперь они выглядят так:

Также к названию команд были добавлены операнды (один или более), которые дают дополнительную информацию для выполнения команды.

Рассмотрим еще один пример программы на ассемблере, которая выводит фразу «Hello, World!«. Пример ассемблированного кода:

Что-то слишком много непонятного кода для такой пустяковой задачи, не правда ли?

Языки программирования высшего уровня

Помните в самом начале я писал, что каждый производитель процессоров делает свою архитектуру? И что у каждой архитектуры свои числовые коды команд?

Так вот одну и ту же программу на ассемблере вам придется «пересобирать» под каждую из архитектур процессора. Для каждой архитектуры нужно скачивать отдельный инструмент Ассемблер и прогонять через него свой код.

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

Так стали появляться языки программирования высокого уровня.

Их суть заключается в том, что цепочки команд на ассемблере были объединены в отдельные функции. Теперь вам достаточно написать одну команду, чтобы показать сообщение «Hello, World!».

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

Первыми появились компилируемые языки программирования. К ним относится С, С++, Java и другие.

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

Рассмотрим чуть подробнее. Например на языке С вывод фразы «Hello, World!» будет выглядеть так: printf(«Hello, World!»). Просто и понятно.

Но процессор не поймет этой команды. Как мы помним, он знает и понимает только маленькие числовые команды. Поэтому компилятор языка C преобразует команду в ассемблированный код, а затем в машинный код, понятный процессору.

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

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

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

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

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

Вот тут в ход идут интерпретируемые языки программирования такие как: Python, PHP, Perl, Pascal и другие.

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

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

Байткод — это код, который понимают все процессоры не зависимо от архитектуры.

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

Подытожим

Байткод — саааамый низкий язык, который понимает процессор.

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

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

Компилятор и Интерпретатор — инструменты, преобразующие код высшего уровня в код, понятный процессору.

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

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

Если вы с чем-то не согласны, у вас есть вопросы или просто хотите сказать спасибо — прошу в комментарии. Пообщаемся 🙂

Читайте также:  что делать если не застыло суфле

Источник

Компиляция Python

Предположим, вы разработали приложение или библиотеку на Python и уже готовитесь передать его / её заказчику. И в этот момент возникают вопросы, о которых многие даже не задумываются.

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

И, наконец, хочется, чтобы конечное приложение работало быстрее, чем в среде разработки.

И вот тут настало время скомпилировать Python-код. Меня зовут Руслан, я старший разработчик компании «Цифровое проектирование». Сегодня я расскажу, как выбрать тот самый компилятор из множества доступных.

AOT/JIT

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

AOT-компиляция (ahead-of-time) – компиляция перед исполнением программы. Т.е. программа компилируется один раз, в результате компиляции получается исполняемый файл.

Бенчмарк

Так как одной из целей является ускорение, необходимо оценить, насколько быстро работает скомпилированный код. В качестве бенчмарка будем использовать pyperfomance. К сожалению, pyperfomance не подошел для Cython и Pythran, потому что не позволяет визуализировать все возможности языка. Ускорения для Cython без модификации кода получить не удалось, а Pythran не умеет в пользовательские классы. Для них воспользуемся вычислением числа пи:

Эксперименты будем проводить на процессоре Intel Core i7 10510U. На CPython 3.9.7 время вычисления числа пи до 100.000.000 знака заняло 5.82 секунды.

AOT-компиляция Python

PyInstaller

PyInstaller упаковывает приложения Python в автономные исполняемые файлы в Windows, GNU / Linux, Mac OS X, FreeBSD, Solaris и AIX.

Устанавливается через pip:

pip install pyinstaller

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

В результате будет создано:

build/ – директория с метаданными для сборки исполняемого файла;

dist/ – директория, содержащая все зависимости и исполняемый файл.

Сборку приложения можно настроить с помощью параметров командной строки:

—name – изменение имени исполняемого файла (по умолчанию, такое же, как у сценария);

—onefile – создание только исполняемого файла (по умолчанию, папка с зависимостями и исполняемый файл);

—hidden-import – перечисление импортов, которые PyInstaller не смог обнаружить автоматически;

—add-data – добавление в сборку файлов данных;

—add-binary – добавление в сборку бинарных файлов;

—exclude-module – исключение модулей из исполняемого файла;

У PyInstaller есть ограничения. Он работает с Python 3.5–3.9. Поддерживает создание исполняемых файлов для разных операционных систем, но не умеет выполнять кросскомпиляцию, т. е. необходимо генерировать исполняемый файл для каждой ОС отдельно. Более того, исполняемый файл зависит от пользовательского glibc, т. е. необходимо генерировать исполняемый файл для самой старой версии каждой ОС.

PyInstaller знает о многих Python-пакетах и умеет их учитывать при сборке исполняемого файла. Но не о всех. Например, фреймворк uvicorn практически весь нужно явно импортировать в файл, к которому будет применена команда pyinstaller. Полный список поддерживаемых из коробки пакетов можно посмотреть здесь.

Cython

Ставится Cython через pip:

pip install Cython

Рассмотрим его работу на примере с вычислением числа пи:

Немного модифицируем нашу функцию:

Cython → C:

Компилируем С-шный код:

И замеряем время на бенчмарке: 3,66 секунды.

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

Создадим файл build.py:

Запустим: python build.py build_ext –-inplace

В результате будет сгенерирован .so/.dll файл.

Nuitka

Ставится через pip:

pip install nuitka

Для генерации исполняемого файла достаточно выполнить команду:

Для компиляции модуля:

Для компиляции пакета:

Pythran

Pythran – статический компилятор Python, позиционирующий себя как ориентированный на научные вычисления и использующий преимущества многоядерных процессоров и блоков инструкций SIMD. Он транслирует Python-код, аннотированный описаниями интерфейса, в C++. До версии 0.9.5 (включительно) Pythran поддерживал Python 3 и Python 2.7. Последние версии поддерживают только Python 3.

pip install pythran

Генерируем бинарный файл .so:

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

Top level statements can only be assignments, strings,functions, comments, or imports

Добавим комментарий аннотации функции:

Скомпилируем и бенчмарк выдает 0,00007 секунды.

cx-Freeze

Ставится с помощью pip:

pip install cx_Freeze

Для генерации исполняемого файла достаточно выполнить команду:

Сборку можно настроить с помощью параметров командной строки:

Также возможно использование сценария сборки, например, так:

Сборка исполняемого файла:

python setup.py build

JIT-компиляция Python

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

PyPy

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

оценщик байт-кода, ответственный за интерпретацию объектов кода Python;

стандартное объектное пространство, отвечающее за создание и управление объектами Python, видимыми приложением.

PyPy поддерживает сотни библиотек Python, включая NumPy.

Основные особенности (сравнение с CPython):

Скорость. При выполнении длительно выполняющихся программ, когда значительная часть времени тратится на выполнение кода Python, PyPy может значительно ускорить ваш код.

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

Скачать PyPy можно с здесь. После скачивания PyPy готов к запуску после распаковки архива. Если необходимо сделать PyPy доступным для всей системы, достаточно поместить символическую ссылку на исполняемый файл pypy в /usr/local/bin. Также можно поставить с помощью pyenv.

PyPy работает на Mac, Linux (не все дистрибутивы) или Windows.

Для запуска кода с помощью PyPy вместо команды python3 (как c помощью CPython) достаточно воспользоваться командой pypy3:

Pyston

В Pyston поддерживаются все возможности CPython, в том числе C API для разработки расширений на языке Си. Среди основных отличий Pyston от CPython помимо общих оптимизаций выделяется использование DynASM JIT и inline-кэширования.

Заключение

Итак, мы рассмотрели 5 фреймворков AOT-компиляции Python. Для любителей аналитики, ниже приведена таблица со сравнительным анализом.

PyInstaller

Cython

Nuitka

Pythran

cx-Freeze

Генерация автономных исполняемых файлов

Компиляция python-модуля в исполняемый файл, совместимый с CPython

Источник

Строительный портал