C++ — помогите переписать с языка python на C++

Содержание

Есть ли какой-то смысл переписывать python-детектилку лиц на C++?

Детектилка работает на либах opencv, caffe, dlib.

Есть ли какой-то смысл переписывать детектилку на С++ (с использованием этих же либ)? Все эти либы вроде скомпилены в .so и Python просто вызывает скомпилённый код, в котором процесс и проводит основное время работы.

Это ясно, но тут другой случай.

Возьми профайлер да посчитай цифру денег

И OpenCV, и Caffe внутри — те самые плюсы. Смысла немного, лучше код почистить.

С учетом того, что детектилка лиц на opencv — два десятка строк кода, не вижу проблем.

Проблемы в том, что надо чётко понимать что делает каждая строка, интерфейсы для python и C++ разные. Нельзя просто так взять и написать в плюсах создание класса с тем же именем и теми же параметрами. Т.е. это дофига работы на самом деле, если говорить о переписывании не самой простой софтины, юзающей не один только opencv.

Есть ли какой-то смысл переписывать детектилку на С++ (с использованием этих же либ)?
Т.е. это дофига работы на самом деле, если говорить о переписывании не самой простой софтины

Лол :-) Сомневаюсь, что тебе нужно притрагиваться к цепепе :-)

Какую задачу ты решаешь? Если перформанс или очень много свободного времени, то имеет.

Раз возник такой вопрос, значит что-то в текущей реализации не устраивает. Перепиши кусок тормозящего кода на плюсах и его заверни в so’шку. Глядишь, так и весь проект постепенно перепишешь.

лучше чистку кода + pypy, просто есть ли смысл тратить ресурсы на переписывание кода, затем его коррекцию, и удаление велосипедов и мусора.

А зачем используете dlib? Чисто ради интереса — что из него тянете?

Если у тебя смесь Си++ и Питона и Питона мало, то переписывай.
Чем меньше в проекте разных языков тем лучше.

Основную часть работ вычислений выполняет ведь C++/C код, так? Тогда прирост от переписывания будет небольшой, в районе нескольких процентов. Я бы стал таким заниматься, только если каждый тик процессора на счету. Экстремальная оптимизация.

Также не забывай, что C++ код требует больших навыков и усилий для написания и поддержания. Задай себе вопрос: стоят ли несколько процентов этого?

Чем меньше в проекте разных языков тем лучше.

Перенос кода из python в C++. Генераторы.

Появилась задачка переделывать большие куски python-кода на C++. Некоторые функции «украшены» yield-ами и являются к тому же рекурсивными, вызывая самих себя в циклах типа «for i in this_func(). «. Есть ли у кого-нить выработанные паттерны разворачивания таких функций в более C++-ный вид? Уж больно страшным и монтрообразным это пока что представляется. Может, boost какой-нибудь или другая «silver-bullet»?

Вобщем, товарищи программисты, помогите кто чем сможет.

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

Цитата (Lazin @ 6.7.2008, 13:34 )
рекурсия для С++ не является чем-то диким

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

Честно говоря мне непонятно зачем нужно переводить программу из Питона в Си. Не проще ли вызывать питоновские фрагменты из Си?

Не понимаю, какая может быть связь между рекурсией и языком программирования.
Давайте отделим мух от котлет, а именно хвостовую рекурсию как альтернативу циклу и алгоритмы, рекурсивные по своей природе. Первым вариантом пользуются только в чисто функциональных языках, и ни в Питоне, ни в Си++ никто в здравом смысле применять эту технику не будет. Во втором случае альтернатива рекурсии — ручное управление стеком. (Берём алгоритмы, для которых рекурсия или итерация — это вопрос константы, не влияющей на O большое. Т.е. не рассматриваем случаи вроде наивного рекурсивного вычисления последовательности Фибоначчи.) Для современных компиляторов это крайне редко даёт ощутимый выигрыш. Для интерпретаторов также имеем сомнительный размен рекурсивного вызова на вызов методов структуры данных (списка, к примеру). И всё это ценой потери читаемости алгоритма: premature optimization и далее по тексту.

Ближе к делу. Лучше всего, конечно, вникнуть в логику и не пытаться скопировать максимально близко к тексту. Генераторы эти, по сути, что делают? Обходят некоторую структуру данных, или может подгружают данные извне, или генерируют некоторую последовательность. Думается, общего метода для переноса генераторов в Си++ нет, точнее, он будет излишне сложным.
Например, можно заменить yield на вызов callback-функции.

Python или C++: что лучше? Давайте узнаем!

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

Я предполгалаю, что у вас нет никакого опыта в программирование и поэтому мы начнем с того, что разберем саму профессию программиста и какие у нее есть преимущества. Даже если вы уже продвинутый программист, эта информация освежит ваши знания. После этого мы рассмотрим каждый язык программирования в отдельности. Затем определим критерии сравнения и сможем ответить на вопрос «Python или C++: как начать программирование с нуля?».

Введение

Мы определились, что программирование является отличной возможностью для развития вашей карьеры. Но почему это так? У каждого человека свои причины, почему он изучает программирование. Но существует определенные причины, которые свойственны всем.

Прежде всего, востребованность работы. Вы наверное много раз слышали о том, что на рынке труда нехватка программистов. Рынок труда в любой момент нуждается в профессиональных программистах. Все, что вам нужно сделать, это сделать простой поиск в Google а запросом «работа программиста» или «работа кодера», и вы увидите бесконечные списки предложений (это варьируется от вашего места жительства). И это тесно связано с темой Python или C++.

Каждый день появляются новые компании, которые занимаются веб-разработкой. Этим компаниям нужны профессиональные программисты, чтобы развивать свои платформы. Но компании не ограничиваются специалистами только в одном языке программирования. Все зависит от проекта, над которым они работают. Помимо этого темы сравнения «Python или C++» популярны. Люди часто пытаются узнать, для чего создан каждый языки подходит ли он под цели, которые ставит программист перед его изучением.

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

Область ИТ (или, если более конкретно – отрасль компьютерных наук) имеет репутацию одной из самых прибыльных отраслей. Аналитики данных и ученые, разработчики программного обеспечения и веб-программисты – это всего лишь несколько профессий, которые зарабатывают на жизнь тем, что они делают. Хоть зарплата не является пунктом номер один, но она находится в топе по заработкам среди всех профессий.

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

Python

Python, созданный еще в 1991 году Гвидо ван Россум, является языком программирования общего назначения, основная функция которого это легкость его чтения. С самого начала язык Python задумывался как максимально простой в использовании. На самом деле простота – это то, чем он известен – в Python используется большое количество пробелов, таким образом код остается легко читаемым, это обеспечивает приятное и простое обучение.

Из-за своей простоты язык Python часто становится предметом споров. Вы можете подумать – с чего бы это? Разве простота это плохо? Хоть простота это преимущество для начинающих, опытные программисты придерживаются другого мнения (это важный момент в сравнении Python или C++).

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

Несмотря на то, что вопрос Python или C++ остается открытым, язык Python обладает важной особенностью. Он подходит под любые проекты – этот язык весьма универсален. Рабочий стол, веб-разработка, обработка данных – все, что вы хотите!

Это была вся информация про язык Python, которая нам пригодится в сравнении Python или C++. Теперь давайте продолжим и поговорим про язык C++.

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

Язык C++ был создан ученым по имени Бьярн Страуструп еще в 1979 году. Хотя изначально он назывался «C с Классами», имя было изменено на «C++» с добавлением нескольких функций в 1983 году. Имейте в виду, что это супер короткая версия того, как появился язык C++ – за этим стоит целая предыстория, но это не наша цель.

Язык C++ является противоположностью Python, если мы говорим с точки зрения простоты. На самом деле он считается одним из самых сложных (если не самый сложный) языков программирования. Его сверхсложный синтаксис позволяет C++ быть чрезвычайно гибким – это основная причина, почему его часто выбирают для работы с проектами, которые разрабатываются для нескольких различных платформ одновременно.

Я уже упоминал в начале сравнения Python или C++, C++ (так же, как Python) также объектно-ориентированный язык программирования. Я уже говорил, что это делает язык быстрым и эффективным, но я так и не объяснил, что на самом деле означает «объектно-ориентированный».

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

Итак, теперь, когда мы знаем немного про сами языки программирования, мы можем перейти к сравнению с Python или C++ и разобрать их по определенным критериям.

Критерии анализа

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

В этой статье мы рассмотрим три момента: скорость, популярность и зарплата специалиста. Рассмотрим каждый из этих пунктов в отдельности.

Скорость

Что касается скорости Python или C++, то это самый обсуждаемый вопрос на форумах по поводу сравнения этих двух языков. И это не без оснований! Хороший язык программирования должен быть быстрым, иначе он будет неэффективным и не сможет сравниться с другими более быстрыми языками. На самом деле добавить что-то еще к этому нечего – эти два языка программирования, о которых идет речь, достаточно быстро взаимодействуют и в отношении их скорости разницы нет.

Популярность

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

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

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

Зарплаты специалистов

Честно говоря, этот пункт самый очевидный для всех.

Как я уже упоминал в начале статьи сравнения Python или C++, программирование действительно очень прибыльная профессия. Тем не менее специалисты в различных языках программирования также зарабатывают по-разному. Это объясняется многими причинами: некоторые компании ставят конкретные требования к специалистам по знаниям языка, другие компании не имеют конкретных требований. Как бы то ни было, факт остается фактом – не все языки имеют одинаковую зарплату.

Python или C++

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

Какой из них быстрее?

Поскольку скорость в сравнении Python или C++ является важным аспектом, о котором мы сначала поговорим.

На первый взгляд после поиска в Интернете, кажется, что C++ более быстрый. Считается, что C++ более быстро исполняется, главным образом потому, что его конкурент – Python – написан на C. Как я уже упоминал, C++ часто рассматривается как самый быстрый язык программирования.

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

Какой язык более популярен?

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

Чья зарплата выше?

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

Согласно сайту Glassdoor.com, разработчики Python могут рассчитывать на получение в среднем 92 000 долларов США в год, что примерно составит 7670 долларов США в месяц. Ожидается, что разработчики C++ будут зарабатывать около 95 000 долларов в год или почти 7920 долларов в месяц. Что эти зарплаты говорят нам?

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

Заключение

Итак, мы подошли к концу нашего сравнения Python или C++. Вам удалось выбрать из двух? Или вы все еще не уверены?

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

Какой бы язык вы ни выбрали, я надеюсь, что эта статья принесла вам больше ясности. Удачи!

Как подружить Python и C++ | Python to bin/exe

Здравствуйте еще раз.

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

Альтернативой данному виду маразма своих начальников вижу компиляцию Python в исполняемое приложение (linux-binary, windows-exe). Что думаете по этому вопросу?

4 Answers

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

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

Создание расширения C++ для Python Create a C++ extension for Python

Модули, написанные на C++ (или C), обычно используются для расширения возможностей интерпретатора Python, а также для доступа к низкоуровневым возможностям операционной системы. Modules written in C++ (or C) are commonly used to extend the capabilities of a Python interpreter as well as to enable access to low-level operating system capabilities. Существует три основных типа модулей: There are three primary types of modules:

  • Модули акселератора: так как Python — это интерпретируемый язык, для повышения производительности некоторые фрагменты кода могут быть написаны на C++. Accelerator modules: because Python is an interpreted language, certain pieces of code can be written in C++ for higher performance.
  • Модули оболочки: предоставляют существующие интерфейсы C/C++ для кода Python или адаптированный API, который удобно использовать в Python. Wrapper modules: expose existing C/C++ interfaces to Python code or expose a more «Pythonic» API that’s easy to use from Python.
  • Модули низкоуровневого системного доступа: созданы для доступа к низкоуровневым функциям среды выполнения CPython, операционной системы и базового оборудования. Low-level system access modules: created to access lower-level features of the CPython runtime, the operating system, or the underlying hardware.

В этой статье рассматривается создание модуля расширения C++ для CPython, вычисляющего гиперболический тангенс и вызывающего его из кода Python. This article walks through building a C++ extension module for CPython that computes a hyperbolic tangent and calls it from Python code. Подпрограмма реализована сначала на языке Python, чтобы продемонстрировать относительный прирост производительности по сравнению с реализацией той же подпрограммы на C++. The routine is implemented first in Python to demonstrate the relative performance gain of implementing the same routine in C++.

В этой статье также показаны два способа сделать C++ доступным для Python: This article also demonstrates two ways to make the C++ available to Python:

  • Стандартные расширения CPython, как описано в документации по Python The standard CPython extensions as described in the Python documentation
  • PyBind11 (рекомендуется для C++ 11 благодаря своей простоте). PyBind11, which is recommended for C++ 11 because of its simplicity.
Цукерберг рекомендует:  Api rest - Интеграция Виртуальной АТС с любой CRM системой по REST API

Сравнение этих и других средств описано в разделе Альтернативные подходы в конце этой статьи. A comparison between these and other means is found under alternative approaches at the end of this article.

Полный пример из этого руководства: python-samples-vs-cpp-extension (GitHub). The completed sample from this walkthrough can be found on python-samples-vs-cpp-extension (GitHub).

Предварительные требования Prerequisites

Visual Studio 2020 или более поздней версии с установленными рабочими нагрузками Разработка классических приложений на C++ и Разработка на Python с параметрами по умолчанию. Visual Studio 2020 or later with both the Desktop Development with C++ and Python Development workloads installed with default options.

В рабочей нагрузке Разработка на Python также установите флажок справа для параметра Собственные средства разработки Python. In the Python Development workload, also select the box on the right for Python native development tools. Этот параметр позволяет настроить большую часть конфигурации, описанной в этой статье. This option sets up most of the configuration described in this article. (Этот параметр также автоматически включает рабочую нагрузку C++.) (This option also includes the C++ workload automatically.)

При установке рабочей нагрузки Приложения для обработки и анализа данных и аналитические приложения по умолчанию включаются среда Python и параметр Собственные средства разработки Python. Installing the Data science and analytical applications workload also includes Python and the Python native development tools option by default.

Дополнительные сведения, в том числе об использовании других версий Visual Studio, см. в руководстве по установке поддержки Python для Visual Studio. For more information, see Install Python support for Visual Studio, including using other versions of Visual Studio. Если вы устанавливаете Python отдельно, обязательно выберите параметры Download debugging symbols (Скачать отладочные символы) и Download debug binaries (Скачать двоичные файлы отладки) в разделе Дополнительные параметры установщика. If you install Python separately, be sure to select Download debugging symbols and Download debug binaries under Advanced Options in the installer. Это гарантирует наличие необходимых отладочных библиотек, если вы решите сделать отладочную сборку. This option ensures that you have the necessary debug libraries available if you choose to do a debug build.

Создание приложения Python Create the Python application

Создайте проект Python в Visual Studio, выбрав Файл > Создать > Проект. Create a new Python project in Visual Studio by selecting File > New > Project. Выполните поиск слова «Python», выберите шаблон Приложение Python, назначьте ему подходящее имя и расположение, а затем нажмите кнопку ОК. Search for «Python», select the Python Application template, give it a suitable name and location, and select OK.

Для работы с C++ необходимо использовать 32-разрядный интерпретатор Python (рекомендуемая версия — Python 3.6 или более поздняя версия). Working with C++ requires that you use a 32-bit Python interpreter (Python 3.6 or above recommended). В окне обозревателя решений в Visual Studio разверните узел проекта, а затем — узел окружения Python. In the Solution Explorer window of Visual Studio, expand the project node, then expand the Python Environments node. Если 32-разрядное окружение не указано как окружение по умолчанию (не выделено жирным шрифтом или меткой глобальное значение по умолчанию), следуйте инструкциям по выбору окружения Python для проекта. If you don’t see a 32-bit environment as the default (either in bold, or labeled with global default), then follow the instructions on Select a Python environment for a project. Если у вас не установлена 32-разрядная версия интерпретатора, см. инструкции по установке интерпретаторов Python. If you don’t have a 32-bit interpreter installed, see Install Python interpreters.

В файл .py проекта вставьте следующий код, отвечающий за тестирование производительности при вычислении гиперболического тангенса (для упрощения сравнения реализуется без использования математической библиотеки). In the project’s .py file, paste the following code that benchmarks the computation of a hyperbolic tangent (implemented without using the math library for easier comparison). Вы можете ввести код вручную, чтобы оценить некоторые функции редактирования Python. Feel free to enter the code manually to experience some of the Python editing features.

Запустите программу с помощью команды Отладка > Запуск без отладки (или нажмите клавиши CTRL+F5), чтобы просмотреть результаты. Run the program using Debug > Start without Debugging (Ctrl+F5) to see the results. Чтобы изменить длительность выполнения тестов производительности, можно настроить переменную COUNT . You can adjust the COUNT variable to change how long the benchmark takes to run. В целях этого руководства задайте значение так, чтобы тест производительности занимал приблизительно две секунды. For the purposes of this walkthrough, set the count so that the benchmark take around two seconds.

При выполнении тестов производительности всегда выбирайте Отладка > Запуск без отладки во избежание издержки при выполнении кода в отладчике Visual Studio. When running benchmarks, always use Debug > Start without Debugging to avoid the overhead incurred when running code within the Visual Studio debugger.

Создание основных проектов C++ Create the core C++ projects

Следуйте инструкциям в этом разделе, чтобы создать два идентичных проекта C++ с именами superfastcode и superfastcode2. Follow the instructions in this section to create two identical C++ projects named «superfastcode» and «superfastcode2». Позже вы используете в каждом проекте разные способы предоставления кода C++ для Python. Later you’ll use different means in each project to expose the C++ code to Python.

Убедитесь, что в переменной среды PYTHONHOME указан путь к интерпретатору Python, который вы собираетесь использовать. Make sure the PYTHONHOME environment variable is set to the Python interpreter you want to use. Проекты C++ в Visual Studio используют эту переменную для поиска различных файлов, например python.h, используемых при создании модулей расширения для Python. The C++ projects in Visual Studio rely on this variable to locate files such as python.h, which are used when creating a Python extension.

Щелкните решение в обозревателе решений правой кнопкой мыши и выберите Добавить > Новый проект. Right-click the solution in Solution Explorer and select Add > New Project. Решение Visual Studio может одновременно содержать проекты Python и C++ (одно из преимуществ использования Visual Studio для Python). A Visual Studio solution can contain both Python and C++ projects together (which is one of the advantages of using Visual Studio for Python).

Выполните поиск «C++», выберите Пустой проект, укажите имя superfastcode (superfastcode2 для второго проекта) и выберите ОК. Search on «C++», select Empty project, specify the name «superfastcode» («superfastcode2» for the second project), and select OK.

Если вы уже установили собственные средства разработки Python в Visual Studio, то можете начать с шаблона Модуль расширения Python, который уже содержит большую часть описываемых ниже функций. With the Python native development tools installed in Visual Studio, you can start with the Python Extension Module template instead, which has much of what’s described below already in place. Но в этом пошаговом руководстве начало работы с пустого проекта позволяет шаг за шагом продемонстрировать создание модуля расширения. For this walkthrough, though, starting with an empty project demonstrates building the extension module step by step. Когда вы освоите процесс, шаблон позволит вам сэкономить время при написании собственных расширений. Once you understand the process, the template saves you time when writing your own extensions.

Создайте файл C++ в новом проекте. Для этого щелкните правой кнопкой мыши узел Исходные файлы и выберите Добавить > Новый элемент, затем выберите Файл C++, присвойте ему имя module.cpp и нажмите кнопку ОК. Create a C++ file in the new project by right-clicking the Source Files node, then select Add > New Item, select C++ File, name it module.cpp , and select OK.

Файл с расширением .cpp нужен, чтобы активировать страницы свойств C++ в последующих шагах. A file with the .cpp extension is necessary to turn on the C++ property pages in the steps that follow.

В обозревателе решений щелкните проект C++ правой кнопкой мыши и выберите пункт Свойства. Right-click the C++ project in Solution Explorer, select Properties.

В верхней части появившегося диалогового окна Страницы свойств задайте для параметра Конфигурация значение Все конфигурации, а для параметра ПлатформаWin32. At the top of the Property Pages dialog that appears, set Configuration to All Configurations and Platform to Win32.

Задайте определенные свойства, как описано в таблице ниже, а затем нажмите кнопку ОК. Set the specific properties as described in the following table, then select OK.

Tab Tab Свойство. Property Значение Value
Общие сведения General Общие > Целевое имя General > Target Name Укажите имя модуля, которое будет использоваться из Python в инструкциях from. import . Specify the name of the module as you want to refer to it from Python in from. import statements. Это же имя используется в C++ при определении модуля для Python. You use this same name in the C++ when defining the module for Python. Если вы хотите применять имя проекта в качестве имени модуля, сохраните значение по умолчанию $(ProjectName). If you want to use the name of the project as the module name, leave the default value of $(ProjectName).
Общие > Целевое расширение General > Target Extension .pyd .pyd
Проект по умолчанию > Тип конфигурации Project Defaults > Configuration Type Динамическая библиотека (.dll) Dynamic Library (.dll)
C/C++ > Общие C/C++ > General Дополнительные каталоги включаемых файлов Additional Include Directories Добавьте подходящую для вашей установки папку include Python, например c:\Python36\include . Add the Python include folder as appropriate for your installation, for example, c:\Python36\include .
C/C++ > Препроцессор C/C++ > Preprocessor Определения препроцессора Preprocessor Definitions Только CPython. Добавьте Py_LIMITED_API; в начало строки (включая точку с запятой). CPython only: add Py_LIMITED_API; to the beginning of the string (including the semicolon). Это определение ограничивает некоторые функции, которые можно вызывать из Python, и расширяет возможности по переносу кода между разными версиями Python. This definition restricts some of the functions you can call from Python and makes the code more portable between different versions of Python. Если вы работаете с PyBind11, не добавляйте это определение. В противном случае вы увидите ошибки сборки. If you’re working with PyBind11, don’t add this definition, otherwise you’ll see build errors.
C/C++ > Создание кода C/C++ > Code Generation Библиотека времени выполнения Runtime Library Многопоточная DLL (/MD) (см. предупреждение ниже) Multi-threaded DLL (/MD) (see Warning below)
Компоновщик > Общие Linker > General Дополнительные каталоги библиотек Additional Library Directories Добавьте подходящую для вашей установки папку Python libs с файлами .lib, например c:\Python36\libs . Add the Python libs folder containing .lib files as appropriate for your installation, for example, c:\Python36\libs . (Обязательно укажите папку libs, содержащую файлы .lib, но не папку LIb, содержащую файлы .py.) (Be sure to point to the libs folder that contains .lib files, and not the Lib folder that contains .py files.)

Если вы не видите вкладку C/C++ в свойствах проекта, значит, в проекте нет файлов, определенных как исходные файлы C и C++. If you don’t see the C/C++ tab in the project properties, it’s because the project doesn’t contain any files that it identifies as C/C++ source files. Такая ситуация может возникнуть, если вы создали исходный файл без расширения .c или .cpp. This condition can occur if you create a source file without a .c or .cpp extension. Например, если ранее вы случайно ввели module.coo вместо module.cpp в диалоговом окне создания элемента, Visual Studio создает файл, но не задает для него тип «Код C/C+», что требуется для активации вкладки свойств C/C++. Такая неправильная идентификация остается актуальной и в случае переименования файла с использованием .cpp . For example, if you accidentally entered module.coo instead of module.cpp in the new item dialog earlier, then Visual Studio creates the file but doesn’t set the file type to «C/C+ Code,» which is what activates the C/C++ properties tab. Such misidentification remains the case even if you rename the file with .cpp . Чтобы правильно задать тип файла, в обозревателе решений щелкните файл правой кнопкой мыши, выберите Свойства, затем установите для параметра Тип файла значение Код C/C++. To set the file type properly, right-click the file in Solution Explorer, select Properties, then set File Type to C/C++ Code.

Для параметра C/C++ > Создание кода > Библиотека времени выполнения обязательно задайте значение Многопоточная библиотека DLL (/MD) даже для конфигурации отладки, так как этот параметр используется при сборке неотладочных двоичных файлов Python. Always set the C/C++ > Code Generation > Runtime Library option to Multi-threaded DLL (/MD), even for a debug configuration, because this setting is what the non-debug Python binaries are built with. Если при использовании CPython вы задали параметр Многопоточная DLL с возможностью отладки (/MDd), при сборке конфигурации Отладка возникает ошибка C1189: Py_LIMITED_API несовместим с Py_DEBUG, Py_TRACE_REFS и Py_REF_DEBUG. With CPython, if you happen to set the Multi-threaded Debug DLL (/MDd) option, building a Debug configuration produces error C1189: Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG. Кроме того, если удалить Py_LIMITED_API (требуется при использовании CPython, но не PyBind11) во избежание этой ошибки сборки, Python аварийно завершает работу при попытке импортировать модуль. Furthermore, if you remove Py_LIMITED_API (which is required with CPython, but not PyBind11) to avoid the build error, Python crashes when attempting to import the module. (Этот сбой возникает в вызове библиотеки DLL PyModule_Create , как описано ниже, и сопровождается сообщением Неустранимая ошибка Python: PyThreadState_Get: нет текущего потока.) (The crash happens within the DLL’s call to PyModule_Create as described later, with the output message of Fatal Python error: PyThreadState_Get: no current thread.)

Параметр /MDd используется для сборки двоичных файлов отладки Python (например, python_d.exe), но его выбор для библиотеки DLL расширения по-прежнему вызывает ошибку сборки Py_LIMITED_API . The /MDd option is used to build the Python debug binaries (such as python_d.exe), but selecting it for an extension DLL still causes the build error with Py_LIMITED_API .

Щелкните проект C++ правой кнопкой мыши и выберите Сборка, чтобы протестировать конфигурации (для отладки и выпуска). Right-click the C++ project and select Build to test your configurations (both Debug and Release). Файлы .pyd находятся в папке solution в каталогах Debug и Release, а не в самой папке проекта C++. The .pyd files are located in the solution folder under Debug and Release, not the C++ project folder itself.

Добавьте следующий код в файл module.cpp проекта: Add the following code to the C++ project’s module.cpp file:

Еще раз выполните сборку проекта C++, чтобы убедиться в правильности кода. Build the C++ project again to confirm that your code is correct.

Если вы еще этого не сделали, повторите предыдущие действия, чтобы создать второй проект с именем superfastcode2 с идентичным содержимым. If you haven’t already done so, repeat the steps above to create a second project named «superfastcode2» with identical contents.

Преобразование проекта C++ в расширения для Python Convert the C++ projects to extensions for Python

Чтобы превратить библиотеку DLL на C++ в расширение для Python, сначала нужно изменить экспортированные методы для взаимодействия с типами Python. To make the C++ DLL into an extension for Python, you first modify the exported methods to interact with Python types. После этого нужно добавить функцию, экспортирующую модуль, а также определения методов модуля. You then add a function that exports the module, along with definitions of the module’s methods.

В последующих разделах объясняется, как выполнять эти действия с помощью расширений CPython и PyBind11. The sections that follow explain how to perform these steps using both the CPython extensions and PyBind11.

Расширения CPython CPython extensions

Пояснения к тому, что показано в этом разделе для Python 3.x, см. в справочном руководстве по API Python/C и, главным образом, в разделе Module Objects (Модульные объекты) на сайте python.org (не забудьте выбрать вашу версию Python в раскрывающемся списке в правом верхнем углу, чтобы увидеть подходящую документацию). For background on what’s shown in this section for Python 3.x, refer to the Python/C API Reference Manual and especially Module Objects on python.org (remember to select your version of Python from the drop-down control on the upper right to view the correct documentation).

Если вы работаете с Python 2.7, см. статьи Extending Python 2.7 with C or C++ (Расширение Python 2.7 с помощью C и C++) и Porting Extension Modules to Python 3 (Перенос модулей расширения на Python 3) на сайте python.org. If you’re working with Python 2.7, refer instead to Extending Python 2.7 with C or C++ and Porting Extension Modules to Python 3 (python.org).

В верхнюю часть module.cpp включите Python.h: At the top of module.cpp, include Python.h:

Измените метод tanh_impl , чтобы он принимал и возвращал типы Python ( PyOjbect* ): Modify the tanh_impl method to accept and return Python types (a PyOjbect* , that is):

Добавьте структуру, определяющую способ представления функции tanh_impl C++ для Python: Add a structure that defines how the C++ tanh_impl function is presented to Python:

Добавьте структуру, которая определяет модуль так, как вы хотите ссылаться на него в своем коде Python, в частности, при использовании оператора from. import . Add a structure that defines the module as you want to refer to it in your Python code, specifically when using the from. import statement. (Сделайте это значением в свойствах проекта в разделе Свойства конфигурации > Общие > Целевое имя.) В приведенном ниже примере имя модуля superfastcode означает, что from superfastcode import fast_tanh можно использовать в Python, так как функция fast_tanh определена в superfastcode_methods . (Make this match the value in the project properties under Configuration Properties > General > Target Name.) In the following example, the «superfastcode» module name means you can use from superfastcode import fast_tanh in Python, because fast_tanh is defined within superfastcode_methods . (Внутренние для проекта C++ имена файлов, такие как module.cpp, являются несущественными.) (Filenames internal to the C++ project, like module.cpp, are inconsequential.)

Добавьте метод, вызываемый Python при загрузке модуля. Он должен иметь имя PyInit_ , где точно соответствует значению свойства Общие > Целевое имя проекта C++ (то есть соответствует имени файла .pyd, созданного проектом). Add a method that Python calls when it loads the module, which must be named PyInit_ , where exactly matches the C++ project’s General > Target Name property (that is, it matches the filename of the .pyd built by the project).

Задайте целевую конфигурацию Выпуск и повторно создайте проект C++, чтобы проверить код. Set the target configuration to Release and build the C++ project again to verify your code. Если возникли ошибки, обратитесь к разделу Устранение проблем, расположенному ниже. If you encounter errors, see the Troubleshooting section below.

PyBind11 PyBind11

Если вы выполнили действия, описанные в предыдущем разделе, вы наверняка заметили, что использовали много стандартного кода для создания необходимых структур модуля для кода C++. If you completed the steps in the previous section, you certainly noticed that you used lots of boilerplate code to create the necessary module structures for the C++ code. PyBind11 упрощает процесс с помощью макросов в файле заголовка C++, которые достигают того же результата с гораздо меньшим объемом кода. PyBind11 simplifies the process through macros in a C++ header file that accomplish the same result with much less code. Сведения о концепциях в этом разделе см. в разделе Основы PyBind11 (github.com). For background on what’s shown in this section, see PyBind11 basics (github.com).

Установите PyBind11 с помощью pip: pip install pybind11 или py -m pip install pybind11 . Install PyBind11 using pip: pip install pybind11 or py -m pip install pybind11 .

В верхнюю часть module.cpp включите pybind11.h: At the top of module.cpp, include pybind11.h:

В нижней части module.cpp используйте макрос PYBIND11_MODULE , чтобы определить точку входа в функцию C++: At the bottom of module.cpp, use the PYBIND11_MODULE macro to define the entrypoint to the C++ function:

Задайте целевую конфигурацию Выпуск и создайте проект C++, чтобы проверить код. Set the target configuration to Release and build the C++ project to verify your code. Если возникли ошибки, читайте следующий раздел об устранении неполадок. If you encounter errors, see the next section on troubleshooting.

Устранение неполадок Troubleshooting

Модуль C++ может не компилироваться по следующим причинам: The C++ module may fail to compile for the following reasons:

Не удалось найти Python.h (E1696: не удается открыть исходный файл Python.h и (или) C1083: не удается открыть включаемый файл: Python.h: отсутствует такой файл или каталог): убедитесь, что путь в разделе C/C++ > Общие > Дополнительные каталоги включаемых файлов в свойствах проекта указывает на папку include установки Python. Unable to locate Python.h (E1696: cannot open source file «Python.h» and/or C1083: Cannot open include file: «Python.h»: No such file or directory): verify that the path in C/C++ > General > Additional Include Directories in the project properties points to your Python installation’s include folder. См. шаг 6 в разделе Создание основного проекта C++. See step 6 under Create the core C++ project.

Не удается найти библиотеки Python. Убедитесь, что путь Компоновщик > Общие > Дополнительные каталоги библиотек в свойствах проекта указывает на папку libs установки Python. Unable to locate Python libraries: verify that the path in Linker > General > Additional Library Directories in the project properties points to your Python installation’s libs folder. См. шаг 6 в разделе Создание основного проекта C++. See step 6 under Create the core C++ project.

Ошибки компоновщика, связанные с целевой архитектурой. Измените архитектуру целевого проекта C++ в соответствии с вашей установкой Python. Linker errors related to target architecture: change the C++ target’s project architecture to match that of your Python installation. Например, если вы хотите использовать в проекте C++ версию Python x64, но у вас установлена версия x86, измените проект C++ для работы с версией х86. For example, if you’re targeting x64 with the C++ project but your Python installation is x86, change the C++ project to target x86.

Тестирование кода и сравнение результатов Test the code and compare the results

Теперь, когда библиотека DLL структурирована как расширения Python, можно ссылаться на них из проекта Python, импортировать модули и использовать их методы. Now that you have the DLLs structured as Python extensions, you can refer to them from the Python project, import the modules, and use their methods.

Предоставление доступа к библиотеке DLL для Python Make the DLL available to Python

Предоставить Python доступ к библиотеке DLL можно двумя способами. There are two ways to make the DLL available to Python.

Первый метод работает, если проект Python и проект C++ находятся в одном решении. The first method works if the Python project and the C++ project are in the same solution. В обозревателе решений щелкните правой кнопкой мыши узел Ссылки в проекте Python и затем выберите команду Добавить ссылку. Go to Solution Explorer, right-click the References node in your Python project, and then select Add Reference. В открывшемся диалоговом окне перейдите на вкладку Проекты, выберите проекты superfastcode и superfastcode2 и нажмите кнопку OK. In the dialog that appears, select the Projects tab, select both the superfastcode and superfastcode2 projects, and then select OK.

Альтернативный метод, описанный далее, предполагает установку модуля в глобальной среде Python и предоставление к нему доступа в других проектах Python. The alternate method, described in the following steps, installs the module in the global Python environment, making it available to other Python projects as well. (При этом обычно требуется обновить базу данных завершения IntelliSense для этой среды в Visual Studio 2020 версии 15.5 и более ранних версий. (Doing so typically requires that you refresh the IntelliSense completion database for that environment in Visual Studio 2020 version 15.5 and earlier. Обновление также требуется и при извлечении модуля из среды.) Refreshing is also necessary when removing the module from the environment.)

Если вы используете Visual Studio 2020 или более поздней версии, запустите Visual Studio Installer, выберите Изменить, затем Отдельные компоненты > Компиляторы, средства сборки и среды выполнения > Набор инструментов Visual C++ 2015.3 версии 140. If you’re using Visual Studio 2020 or later, run the Visual Studio installer, select Modify, select Individual Components > Compilers, build tools, and runtimes > Visual C++ 2015.3 v140 toolset. Этот шаг необходим, так как Python (для Windows) сам создан с помощью Visual Studio 2015 (версия 14.0) и поэтому ожидает наличия этих средств при создании расширения одним из описанных здесь способов. This step is necessary because Python (for Windows) is itself built with Visual Studio 2015 (version 14.0) and expects that those tools are available when building an extension through the method described here. (Обратите внимание, что может потребоваться установить 32-разрядную версию Python и нацелить библиотеку DLL на Win32, а не на x64.) (Note that you may need to install a 32-bit version of Python and target the DLL to Win32 and not x64.)

Создайте в проекте C++ файл с именем setup.py, щелкнув проект правой кнопкой мыши и выбрав пункт Добавить > Новый элемент. Create a file named setup.py in the C++ project by right-clicking the project and selecting Add > New Item. Выберите тип файла Файл C++ (.cpp), присвойте файлу имя setup.py и щелкните ОК. (Присвоение файлу расширения .py позволяет Visual Studio распознавать его как файл Python несмотря на использование шаблона файла C++.) Then select C++ File (.cpp), name the file setup.py , and select OK (naming the file with the .py extension makes Visual Studio recognize it as Python despite using the C++ file template). Когда файл откроется в редакторе, вставьте в него следующий код в зависимости от метода расширения: When the file appears in the editor, paste the following code into it as appropriate to the extension method:

Расширения CPython (проект superfastcode): CPython extensions (superfastcode project):

Документация к этому скрипту приведена в статье о создании расширений на C и C++ (python.org). See Building C and C++ extensions (python.org) for documentation on this script.

PyBind11 (проект superfastcode2): PyBind11 (superfastcode2 project):

При использовании в командной строке код setup.py предписывает Python создать расширение с помощью набора инструментов C++ Visual Studio 2015. The setup.py code instructs Python to build the extension using the Visual Studio 2015 C++ toolset when used from the command line. Откройте командную строку с повышенными привилегиями, перейдите в папку с проектом C++ (то есть в папку, содержащую setup.py), а затем введите следующую команду: Open an elevated command prompt, navigate to the folder containing the C++ project (that is, the folder that contains setup.py), and enter the following command:

Вызов библиотеки DLL из Python Call the DLL from Python

После того как вы предоставили библиотеки DLL для Python, как описано в предыдущем разделе, вы можете вызвать функции superfastcode.fast_tanh и superfastcode2.fast_tanh2 из кода Python и сравнить их эффективность с реализацией Python: After you’ve made the DLL available to Python as described in the previous section, you can now call the superfastcode.fast_tanh and superfastcode2.fast_tanh2 functions from Python code and compare their performance to the Python implementation:

Добавьте приведенные ниже строки в файл .py, чтобы вызвать методы, экспортированные из библиотек DLL, и отобразить их выходные данные: Add the following lines in your .py file to call methods exported from the DLLs and display their outputs:

Запустите программу Python (Отладка > Запуск без отладки или CTRL+F5) и убедитесь, что подпрограмма C++ выполняется примерно в 5–20 раз быстрее, чем реализация Python. Run the Python program (Debug > Start without Debugging or Ctrl+F5) and observe that the C++ routines run approximately five to twenty times faster than the Python implementation. Обычно выводится следующий результат. Typical output appears as follows:

Если команда Запуск без отладки недоступна, в обозревателе решений щелкните правой кнопкой мыши проект Python и выберите команду Назначить запускаемым проектом. If the Start Without Debugging command is disabled, right-click the Python project in Solution Explorer and select Set as Startup Project.

Попробуйте увеличить значение переменной COUNT , чтобы разница стала еще очевиднее. Try increasing the COUNT variable so that the differences are more pronounced. Кроме того, отладочная сборка модуля C++ выполняется медленнее, чем сборка выпуска, так как отладочная сборка менее оптимизирована и включает в себя разные проверки ошибок. A Debug build of the C++ module also runs slower than a Release build because the Debug build is less optimized and contains various error checks. Вы можете свободно переключаться между этими конфигурациями для их сравнения. Feel free to switch between those configurations for comparison.

В выходных данных вы увидите, что расширение PyBind11 не такое быстрое, как расширение CPython, хотя все равно значительно быстрее, чем прямая реализация на языке Python. In the output, you can see that the PyBind11 extension isn’t as fast as the CPython extension, though it’s still significantly faster than the straight Python implementation. Разница связана с небольшим количеством издержек для отдельных вызовов, которые использует PyBind11, чтобы значительно упростить интерфейс C++. The difference is due to a small amount of per-call overhead that PyBind11 introduces in order to make its C++ interface dramatically simpler. Это различие для одного вызова почти незаметно, но так как тестовый код вызывает функции расширения 500 000 раз, издержки накапливаются. This per-call difference is actually quite negligible: because the test code calls the extension functions 500,000 times, the results you see here greatly amplify that overhead! Как правило, функция C++ выполняет гораздо больше работы, чем обычные методы fast_tanh[2] , используемые здесь, в этом случае издержки не имеют значения. Typically, a C++ function does much more work than the trivial fast_tanh[2] methods used here, in which case the overhead is unimportant. Но если вы реализуете методы, которые могут вызываться тысячи раз в секунду, подход CPython будет иметь лучшую производительность по сравнению с PyBind11. However, if you’re implementing methods that might be called thousands of times per second, using the CPython approach can result in better performance than PyBind11.

Отладка кода C++ Debug the C++ code

Visual Studio поддерживает совместную отладку кода на Python и C++. Visual Studio supports debugging Python and C++ code together. В этом разделе этот процесс рассматривается на примере проекта superfastcode. Для проекта superfastcode2 действия будут аналогичными. This section walks through the process using the superfastcode project; the steps are the same for the superfastcode2 project.

Щелкните проект Python правой кнопкой мыши в обозревателе решений, выберите Свойства, откройте вкладку Отладка и выберите Отладка > Разрешить отладку машинного кода. Right-click the Python project in Solution Explorer, select Properties, select the Debug tab, and then select the Debug > Enable native code debugging option.

При включении отладки машинного кода окно вывода Python может исчезнуть сразу после завершения программы без обычной паузы с сообщением Для продолжения нажмите любую клавишу. When you enable native code debugging, the Python output window may disappear immediately when the program has completed without giving you the usual Press any key to continue pause. Чтобы сделать паузу принудительно, добавьте параметр -i в поле Запуск > Аргументы интерпретатора на вкладке Отладка при включении отладки машинного кода. To force a pause, add the -i option to the Run > Interpreter Arguments field on the Debug tab when you enable native code debugging. Этот аргумент переводит интерпретатор Python в интерактивный режим по завершении кода, после чего он ожидает нажатия клавиш CTRL+Z > ВВОД для выхода. This argument puts the Python interpreter into interactive mode after the code finishes, at which point it waits for you to press Ctrl+Z > Enter to exit. (Кроме того, если вы не против изменения кода Python, можно добавить в конец программы операторы import os и os.system(«pause») . (Alternately, if you don’t mind modifying your Python code, you can add import os and os.system(«pause») statements at the end of your program. Этот код дублирует исходный запрос с паузой.) This code duplicates the original pause prompt.)

Чтобы сохранить изменения свойств, выберите пункт меню Файл > Сохранить. Select File > Save to save the property changes.

На панели инструментов Visual Studio измените конфигурацию сборки на режим Отладка. Set the build configuration to Debug in the Visual Studio toolbar.

Так как в отладчике код, как правило, выполняется дольше, может потребоваться уменьшить значение переменной COUNT в файле .py приблизительно в пять раз (например, вместо 500000 укажите 100000 ). Because code generally takes longer to run in the debugger, you may want to change the COUNT variable in your .py file to a value that’s about five times smaller (for example, change it from 500000 to 100000 ).

В коде C++ установите точку останова в первой строке метода tanh_impl , а затем запустите отладчик (F5 или Отладка > Начать отладку). In your C++ code, set a breakpoint on the first line of the tanh_impl method, then start the debugger (F5 or Debug > Start Debugging). При вызове этого кода отладчик останавливается. The debugger stops when that code is called. Если точка останова не сработает, проверьте, выбрана ли конфигурация отладки и сохранен ли проект (при запуске отладчика он не сохраняется автоматически). If the breakpoint is not hit, check that the configuration is set to Debug and that you’ve saved the project (which does not happen automatically when starting the debugger).

На этом этапе вы можете пошагово выполнять код на C++, проверять переменные и т. д. At this point you can step through the C++ code, examine variables, and so on. Эти возможности подробно описаны в руководстве по совместной отладке C++ и Python. These features are detailed in Debug C++ and Python together.

Альтернативные подходы Alternative approaches

Существуют различные средства для создания расширений Python, как описано в таблице ниже. There are a variety of means to create Python extensions as described in the following table. Первые две записи для CPython и PyBind11 уже обсуждались в этой статье. The first two entries for CPython and PyBind11 are what has been discussed in this article already.

Подход Approach Появление Vintage Представители Representative user(s) Преимущества Pro(s) Недостатки Con(s)
Модули расширений C/C++ для CPython C/C++ extension modules for CPython 1991 1991 Стандартная библиотека Standard Library Подробная документация и учебники. Extensive documentation and tutorials. Полный контроль. Total control. Компиляция, переносимость, управление ссылками. Compilation, portability, reference management. Хорошее знание C. High C knowledge.
PyBind11 (рекомендуется для C++) PyBind11 (Recommended for C++) 2015 2015 Упрощенная библиотека заголовков для создания привязок Python к существующему коду C++. Lightweight, header-only library for creating Python bindings of existing C++ code. Малое число зависимостей. Few dependencies. Совместимость с PyPy. PyPy compatibility. Новый, менее проверенный подход. Newer, less mature. Частое использование функций C++11. Heavy use of C++11 features. Краткий список поддерживаемых компиляторов (включает Visual Studio). Short list of supported compilers (Visual Studio is included).
Cython (рекомендуется для C) Cython (Recommended for C) 2007 2007 gevent, kivy gevent, kivy Аналогичен Python. Python-like. Высокая степень зрелости. Highly mature. Высокая производительность. High performance. Компиляция, новый синтаксис, новая цепочка инструментов. Compilation, new syntax, new toolchain.
Boost.Python Boost.Python 2002 2002 Работает практически с любым компилятором C++. Works with just about every C++ compiler. Большой и сложный набор библиотек. Содержит много обходных путей для старых компиляторов. Large and complex suite of libraries; contains many workarounds for old compilers.
ctypes ctypes 2003 2003 oscrypto oscrypto Отсутствие компиляции, широкая доступность. No compilation, wide availability. Обращение к структурам C и их изменение затруднено и подвержено ошибкам. Accessing and mutating C structures cumbersome and error prone.
SWIG SWIG 1996 1996 crfsuite crfsuite Создание привязок сразу для нескольких языков. Generate bindings for many languages at once. Чрезмерные затраты, когда единственной целью является Python. Excessive overhead if Python is the only target.
cffi cffi 2013 2013 cryptography, pypy cryptography, pypy Простота интеграции, совместимость с PyPy. Ease of integration, PyPy compatibility. Новый, менее проверенный подход. Newer, less mature.
cppyy cppyy 2020 2020 Подобен cffi при использовании C++. Similar to cffi using C++. Новый, возможны проблемы с VS 2020. Newer, may have some issues with VS 2020.

См. также See also

Полный пример из этого руководства: python-samples-vs-cpp-extension (GitHub). The completed sample from this walkthrough can be found on python-samples-vs-cpp-extension (GitHub).

Можете простым языком объяснить разницу между языками программирования Python и C++?

Считается, что язык C++ является расширением (надстройкой) языка C, потому речь обычно ведут про C/C++. Текст на С/C++ в основном кросс-платформенный, то есть может работать на любой архитектуре процессора, при условии что для нее будет разработан компилятор C++ (инструмент, с помощью которого разработчик выполняет построение текста в программу). Текст программы на си/плюсах нельзя просто запустить, его нужно компилировать, например в Exe-файл. Во многом большая часть современных операционных систем и драйверов написаны на C или С++, поскольку обеспечивают максимальное быстродействие и «нативны» (дают текст ассемблера, языка процессора). В отличие от многих других языков программирования, C/C++ работает практически на всех современных устройствах и процессорах, но на чистом языке нельзя создать программу, разработчики устройств поддерживают требуемые зависимости, индивидуальные для различных платформ. Это второе узкое место языка, снижающее универсальность (но не последнее).

Python – это язык, текст которого не компилируется, а сразу выполняется на виртуальной машине, запуская конечную программу. Виртуальная машина пайтона написана на C, таким образом, код на языке Python можно запустить из-нутри программы на C, чем и является классичский интерпретатор python, которым вы пользуетесь, и другие программы, например, роботтехника или игры, в которых используется python. Наконец, текст на языке Python нельзя запустить на “голом железе”. При этом, для работы python приложения нужно так же уйма дополнительных компонентов (packages), которые должны быть установлены или предоставлены виртуальной машине. (Виртуальной машиной называется изолированное пространство памяти, потоков и стека, то есть основа работы программы. В одном программе может параллельно выполняться множество python-машин). Python более универсален, чем нативные языки, посколько один и тот же текст может быть во многих случаях успешно использован на разных платформах и процессорах, при условии, что система предоставила требуемые packages, которые использовал программист. При том каждая программа на python сама по себе package.

Языки различаются синтаксисом, то есть основными конструкциями и регламентом, используемыми программистом. Например, C/C++ и подобные им языки так и называют — C-like languages, в них доминируют фигурная, круглая и квадратные скобки. Пайтон же, в свою очередь, пытается упростить объем текста, который пишет программист, для этого где «не требуется» скобки опускаются, а для разделения блоков используются отступы (tabs) длиной традиционно в 4 пробела, в то время, как программу на C/C++ любой сложности можно написать в одну строку, если очень захотеть. В итоге python имеет альтернативный синтаксис.

Язык Python популярен именно благодаря этим отличиям от C/C++. Говоря про сходства, их очень много. Здесь и поддержка классов/объектов, автоматического управления памятью, лямбда-функции и прочие динамичные трюки, словом Python и С++ ближайшие соседи, в слегка разном исполнении, для разной аудитории и целей. Многие другие языки программирования в течение долгих лет пытались создать альтернативу Python, как на базе принципа VM, так и другими методами, но не один по всей видимости не выдержал конкуренции за место простого, динамичного и расширяемого свободного языка, даже Java.

В дальнем будущем python может оказаться вытеснен языком Go, который устраняет проблемы самого python’а и сохраняет достоинства C/C++ перед ним, но не теряет flexibility. C/C++ же на пенсию не собираются по определению, хотя есть иные точки зрения.

Встраивание Python в C/C++: первая часть

Written on 02 Марта 2014 .

ОГЛАВЛЕНИЕ

Статья познакомит программистов C/C++ с Python/C API, библиотекой C, помогающей встраивать модули Python в приложения C/C++. Библиотека API предоставляет множество подпрограмм C для инициализации интерпретатора Python, вызова модулей Python и завершения встраивания. Библиотека скомпилирована с Python и распространяется со всеми последними выпусками Python.

Введение

Статья «Встраивание Python в многопоточные приложения C/C++» (Linux Journal) вдохновила на более глубокое освещение темы встраивания Python. Эта статья написана с двумя целями:
1. Она написана для программистов, более опытных в C/C++, чем в Python. Руководство применяет практический подход и пропускает все теоретические рассуждения.
2. Постараться сохранить межплатформенную совместимость Python при написании кода встраивания.
Имеются модули, написанные другими на Python, которые надо использовать. Вы разбираетесь в C/C++, но мало знакомы с Python. Нет инструмента для преобразования их в код C, как преобразование из FORTRAN. Однако некоторые инструменты генерируют исполнимый модуль из модуля Python. Но они не решают проблему. Преобразование кода в исполнимые модули обычно все усложняет, так как приходится выяснять, как приложение C/C++ взаимодействует с исполнимым «черным ящиком».

Первая часть серии статей рассматривает основы встраивания Python. Вторая часть переходит к более продвинутым темам. Это руководство не обучает языку Python систематически, но кратко описывается, как работает код Python, когда он появляется. Акцент будет на то, как внедрить модули Python в приложения C/C++. Смотрите статью: «Встраивание Python в C/C++: вторая часть».

Чтобы использовать исходный код, надо установить последний выпуск Python, Visual C++ (или компилятор GCC на Linux). Тесты проводились в следующей среде: Python 2.4 (Windows и Linux), Visual C++ 6.0 (Windows) или GCC 3.2 (RedHat 8.0 Linux). В случае Visual C++ выберите конфигурацию выпуска для компиляции. Конфигурация отладки требует библиотеку отладки Python «python24_d.lib», не поставляемую с нормальными сборками.

Справка

Python – мощный интерпретируемый язык, как Java, Perl и PHP. Он обладает множеством прекрасных свойств, ожидаемых программистами, в том числе «простотой» и «переносимостью». Помимо доступных инструментов и библиотек, язык Python хорошо подходит для моделирования. Он бесплатный, и инструменты и библиотеки, написанные для программистов Python, тоже бесплатные. Более подробно о языке читайте на официальном сайте.

Азы встраивания: функции, классы и методы

Сначала рассматривается пример программы на C, вызывающей функцию в модуле Python. Ниже приведен исходный файл «call_function.c»:

Исходный файл Python «py_function.py» выглядит так:

Проверки на действительность объектов пропускаются для краткости. В Windows компилируется исходник C и получается исполнимый модуль по имени «call_function.exe». Для его запуска введите в командную строку «call_function py_function multiply». Второй аргумент является именем файла Python (без расширения), который при загрузке становится именем модуля. Третий аргумент является именем функции Python, вызываемой в модуле. Исходник Python не участвует в компиляции или компоновке; он только загружается и интерпретируется во время выполнения. Вывод из выполнения следующий:

Сам код C не требует разъяснений, не считая того, что:

• Все в Python является объектом. pDict и pFunc являются заимствованными ссылками, поэтому не нужно Py_DECREF() их.
• Все вызовы Py_XXX и PyXXX_XXX являются вызовами Python/C API.
• Код компилируется и выполняется на всех платформах, поддерживаемых Python.

Теперь надо передать аргументы функции Python. Добавляется блок для обработки аргументов для вызова:

Новый исходник C добавляет блок «Подготовить список аргументов для вызова» и проверку возвращаемого значения. Он создает кортеж (спископодобный тип) для хранения всех параметров для вызова. Выполнение команды «call_function py_source multiply1 6 7» дает вывод:

Легко писать классы на Python. Также легко использовать класс Python в коде C. Надо лишь создать экземпляр объекта и вызвать его методы, так же как вызываются нормальные функции. Пример ниже:

Третий параметр для PyObject_CallMethod(), «(ii)» является форматирующей строкой, указывающей, что следующие аргументы – два целых числа. PyObject_CallMethod() принимает типы переменных C как свои аргументы, а не как объекты Python. Этим он отличается от других вызовов, встречавшихся до сих пор. Исходник Python «py_class.py» выглядит так:

Для запуска приложения добавляется имя класса между именами модуля и функции, являющейся «Multiply» в данном случае. Командная строка становится «call_class py_class Multiply multiply» или «call_class py_class Multiply multiply2 9 9».

C/C++ и Python = Boost.Python на Windows

Для многих не секрет, что Python�� не блещет скоростью обработки большого количества данных. При этом обладает преимуществом легкого подключения расширений на C/C++. Я писал о расширениях C в этой статье, а здесь рассмотрен альтернативный способ с помощью популярной С++ библиотеки Boost.

Рассказывает Роман Щеголихин. А расширение будет подключаться к Python 2.7��.

Постановка задачи

Питон работает медленно относительно бинарного кода. Критичные участки вычислений имеет смысл вынести во внешний исполняемый файл, написанный на C/C++. Но сразу возникает вопрос — как обмениваться данными, вернее, в каком формате?

Первое, что мне удалось сделать — это, используя модуль CTypes, подключить dll, написанную на C++, которая рассчитывала корреляционную матрицу. Стояла задача за приемлемое время обработать порядка 10 млн пар массивов ёмкостью около 500-600 элементов типа double. Dll писалась на Visual Studio 2015 с использованием библиотеки OpenMP. Мне удалось сократить время расчета с нескольких десятков минут до примерно 220 сек. Наверно, можно и ещё быстрее, если считать на GPU.

Узким местом оказался обмен данными между питоном и C++.

Моё решение заключалось в передаче входных и выходных данных в виде строки с разделителями. Python-скрипт “запаковывал” исходные данные в строку и передавал её в качестве параметра в dll. Внутри dll происходила “распаковка” входных данных в векторы STL и производились расчеты. Результаты помещались в строку и отправлялись обратно в Python-скрипт, где распаковывались.

Хотелось избавиться от операций со строками и передавать в питон (и принимать, конечно) его родные типы данных. В идеале сразу в виде массивов Numpy или в виде каких-либо ещё более функциональных объектов.

Реализация

Существует несколько способов взаимодействия в связке Python ↔ С++. Ниже рассматривается использование библиотеки Boost.Python. Это одна из многих библиотек в составе Boost. Она позволяет обмениваться данными, которые будут понятны на обоих сторонах. Поддерживается обработка исключений. Классы C++ можно заворачивать в вид, “понятный” питону. Причем можно исполнять код питона внутри C++. И многое другое!

Библиотека бесплатна и реализована для всех основных платформ, включая Linux и Windows. Функционал у неё огромный! Документация исчерпывающая, но местами не хватает примеров, поэтому для себя (чтобы не забыть и не потерять) и для всех, кому это может быть полезно, ниже я привожу несколько примеров по использованию библиотеки Boost.Python.

Все примеры ниже рассматриваются для Windows и Python 2.7 разрядности 64 bit. IDE разработки MS Visual Studio 2015. При необходимости всё то же самое можно повторить и под Linux. А также под другую версию и разрядность питона. Важно только соблюдать соответствие разрядности установленного питона и разрядности используемой библиотеки Boost.

Установка Boost

На этом этапе в системе уже должен быть установлен Python. Желательно, чтобы он был добавлен в состав переменной PATH. Тогда команда python будет запускаться из любого места. Проверьте, работает у вас? Заодно посмотрите разрядность вашего питона. Я потратил много времени пытаясь на 64-разрядном питоне запустить dll, которую собирал для 32-разрядной платформы. У меня в системе сейчас такой питон:

C# vs C++ vs Python, как первый язык программирования

Что же лучше для новичка?Не могу понять хорош ли питон для начала?Одни говорят что да, другие что нет.Кто то говорит что C++ через пару лет умрет, будущие за C# и т.д. Все говорят что шарп легче, но мне было гораздо приятней писать конвертер на плюсах.Может потом на плюсах что то ужасное?

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

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

Для обучения: совсем первый язык — это C. Для ООП — ява или C# (C++ только в случае, если все слишком хорошо прошло с C).
Если, таки, C++ хорошо знать, то другие императивные языки учатся за 40 минут каждый.

AmigoNikita
> Кто то говорит что C++ через пару лет умрет, будущие за C# и т.д.
угу так говорят ещё со времён появления явы а это уже 16 лет. (к тому же щас только началась эпоха возражения С++ ;7 )
AmigoNikita
> Что же лучше для новичка?
бери питон он формирует грамотный стиль написания и базовые знания ооп. потом бери С++ научишься работать с памятью и вообще поймёшь как всё работает.
потом бери С# для формошлёпства.
Chipmunk
> Если, таки, C++ хорошо знать, то другие императивные языки учатся за 40 минут
> каждый.
+100

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

AmigoNikita
> C#
я за C#. причина простая— громадное количество документации

За путхон.
Чтобы кот научился форматировать.

Chipmunk
> Если, таки, C++ хорошо знать, то другие императивные языки учатся за 40 минут
> каждый.
Попробуй выучить D хотя бы за сорок часов :)

Chaos_Optima
> к тому же щас только началась эпоха возражения С++
Вот как раз на это ничто не указывает. Даже выход нового стандарта и даже то, что в студию воткнули некоторые из его фич. Наоборот бурления говн всё больше и больше.

Chipmunk
> Для обучения: совсем первый язык — это C.

Кстати, для меня самое важное выучить Objective-C, но мне советовали с него не начинать и выучить сначало C++.А питон чисто для. даже не знаю чего, но говорят в игрострое полезный очень как дополнительный язык.И какого вы мнения о книге «Освой самостоятельно C++ за 21 день» Какие возможности у меня будут после прохождения?

AmigoNikita
> И какого вы мнения о книге «Освой самостоятельно C++ за 21 день» Какие
> возможности у меня будут после прохождения?

Это бесполезно. Программирование это не какой-то язык, а алгоритмы и структуры данных. Именно их и нужно тебе изучать, — можешь начать с книжки Н. Вирта, которая так и называется «Алгоритмы и структуры данных». Правда, там Паскаль (по крайней мере в том издании, что я видел в последний раз).

AmigoNikita
> Кстати, для меня самое важное выучить Objective-C, но мне советовали с него не
> начинать и выучить сначало C++.
Советчикам скажи, что они дураки. Obj-C это элегантная объектно-ориентированная надстройка над Си, они даже полностью обратно совместимы, его (Си) и учить надо в первую очередь. А кресты только извратят восприятие ООП, сделав переход на нормальные языки малопродуктивным, ты не будешь знать, чем Си отличается от С++ и не сможешь перестроиться обратно. Хотя наверняка рантайм Obj-C тоже в большой степени влияет на его отличие от предка.

Vladar
> Ни в коем случае: http://www.stolyarov.info/files/anti_c_v03.pdf
Да, использование Паскаля дает возможность тем, кому не дано, получать в универе хоть какие-то оценки.
Но при этом, такое обучение тормозит тех, кто реально потом будет программистом.

На самом деле главное — это понять низкие уровни. Это просто изучением языка не решается (даже асма).

Преобразование программы Python в код C/С++?

Можно ли преобразовать программу Python в C/С++?

Мне нужно реализовать пару алгоритмов, и я не уверен, что разрыв в производительности достаточно велик, чтобы оправдать всю боль, с которой я столкнулся, когда делаю это на C/С++ (что у меня плохо получается). Я подумал о написании одного простого алгоритма и сравнил его с таким преобразованным решением. Если только это будет значительно быстрее, чем версия Python, тогда у меня не будет другого выбора, кроме как сделать это на C/С++.

Да. Посмотрите Cython. Он делает именно это: конвертирует Python в C для ускорения.

Если для варианта C требуется x часов меньше, я бы потратил на это время, позволяя алгоритмам работать дольше/снова

«инвестировать» здесь не самое подходящее слово.

Создайте рабочую реализацию в Python. Вы закончите это задолго до того, как закончите версию C.

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

Если он все еще слишком медленный, вручную переведите хорошо продуманный и тщательно сконструированный Python в C.

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

Эта цитата важна.

Правило Томпсона для производителей телескопов в первый раз
Быстрее сделать четырехдюймовое зеркало и затем шестидюймовое зеркало, чем сделать шестидюймовое зеркало.

Shed Skin является «(ограниченным) компилятором Python-to-С++».

Просто наткнулся на этот новый инструмент в новостях хакера.

С их страницы — «Nuitka» является хорошей заменой для интерпретатора Python и компилирует каждую конструкцию, предлагаемую CPython 2.6, 2.7, 3.2 и 3.3. Она переводит Python в программу на С++, которая затем использует «libpython» для выполнения в так же, как и CPython, очень совместимым способом. «

Другой вариант — конвертировать в C++ помимо Shed Skin — это Pythran.

Чтобы процитировать высокопроизводительный Python от Михаила Горелика и Яна Озсвальда:

Pythran — это компилятор Python-to- C++ для подмножества Python, которое включает частичную поддержку numpy . Он действует немного как Numba и Cython — вы аннотируете аргументы функций, а затем вступаете во владение дальнейшими аннотациями типов и специализацией кода. Он использует возможности векторизации и возможности распараллеливания на основе OpenMP. Он работает только на Python 2.7.

Одна очень интересная особенность Pythran заключается в том, что он будет пытаться автоматически определять возможности распараллеливания (например, если вы используете map ) и превращать это в параллельный код, не требуя от вас дополнительных усилий. Вы также можете указать параллельные секции используя директивы pragma omp >; в этом отношении он очень похож на поддержку Cythons OpenMP.

За кулисами Pythran возьмет как обычный Python, так и код numpy и попытается агрессивно скомпилировать их в очень быстрый C++ — даже быстрее, чем результаты Cython.

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

http://code.google.com/p/py2c/ выглядит как возможность — они также упоминают на своем сайте: Cython, Shedskin и RPython и подтверждают, что они конвертируют код Python на чистый C/С++, который намного быстрее, чем C/С++, пронизанный вызовами API Python. Примечание: я не пробовал, но я собираюсь..

Я понимаю, что ответ на совершенно новое решение отсутствует. Если в коде используется Numpy, я бы посоветовал попробовать Pythran:

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

Преимущество по сравнению с Cython заключается в том, что вам просто нужно использовать Pythran для функции Python, оптимизированной для Numpy, что означает, что вам не нужно расширять циклы и добавлять типы для всех переменных в цикле. Pythran не спешит анализировать код, поэтому он понимает операции над numpy.ndarray .

Это также огромное преимущество по сравнению с Numba или другими проектами, основанными на компиляции «точно вовремя», для которых (насколько мне известно) вам нужно расширить циклы, чтобы быть действительно эффективными. И тогда код с петлями становится очень неэффективным, используя только CPython и Numpy.

Недостаток Pythran: нет классов! Но поскольку только функции, которые действительно нужно оптимизировать, должны быть скомпилированы, это не очень раздражает.

Другой момент: Pythran хорошо поддерживает (и очень легко) OpenMP parallelism. Но я не думаю, что поддерживается mpi4py.

Я знаю, что это старая ветка, но я хотел дать полезную информацию.

Я лично использую PyPy, который очень легко установить с помощью pip. Я взаимозаменяемо использую интерпретатор Python/PyPy, вам вообще не нужно менять код, и я обнаружил, что он примерно в 40 раз быстрее, чем стандартный интерпретатор Python (либо Python 2x, либо 3x). Я использую PyCharm Community Edition для управления своим кодом, и мне это нравится.

Мне нравится писать код на python, так как я думаю, что он позволяет вам больше сосредоточиться на задаче, чем на языке, что для меня является огромным плюсом. И если вам нужно, чтобы он был еще быстрее, вы всегда можете скомпилировать двоичный файл для Windows, Linux или Mac (не прямо, но возможно с другими инструментами). Исходя из моего опыта, я получаю примерно 3,5-кратное ускорение по сравнению с PyPy при компиляции, то есть в 140 раз быстрее, чем у Python. PyPy доступен для кода Python 3x и 2x, и снова, если вы используете IDE, такую как PyCharm, вы можете очень легко поменять местами, скажем, PyPy, Cython и Python (хотя требуется немного первоначального изучения и настройки).

Некоторые могут поспорить со мной об этом, но я считаю, что PyPy работает быстрее, чем Cython. Но они оба отличный выбор.

Изменить: Я хотел бы сделать еще одну небольшую заметку о компиляции: когда вы компилируете, результирующий двоичный файл намного больше, чем ваш скрипт на Python, поскольку он встраивает в него все зависимости и т.д. Но тогда вы получите несколько явных преимуществ: скорость !, теперь приложение будет работать на любом компьютере (в зависимости от того, для какой ОС вы скомпилировали, если не все. lol) без Python или библиотек, оно также запутывает ваш код и технически готово к работе (в некоторой степени). Некоторые компиляторы также генерируют C-код, который я на самом деле не видел и не видел, полезен ли он или просто бред. Удачи.

Цукерберг рекомендует:  Статические сайты на гребне волны
Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих