Преобразовать программу Python в код C / C ++? [закрыто]

149

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

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

CrazyFlyingCloseline
источник
32
Столько, сколько Python проигрывает в тестах, имейте в виду, что это 50-кратное или 100-кратное замедление все еще невозможно, если вычисление завершается через несколько секунд в Python, и даже не верно, когда вы выполняете много операций ввода-вывода или имеете ужасный алгоритм. Вместо того, чтобы спрашивать "насколько медленнее Python?" Вы должны спросить "достаточно ли быстр Python?" (и это наиболее вероятно, честно) - это также быстрее, чем сравнительный анализ или запрос здесь.
1
Реализация алгоритма на python довольно быстрая и понятная ... вам просто нужно сделать это, а затем проверить, достаточно ли он быстр. В большинстве случаев вы можете оптимизировать алгоритм, чтобы он работал намного быстрее, используя разные структуры данных (dict / sets вместо lists ...) или различные операции. В любом случае, оптимизация должна произойти после того, как вы уже реализовали первый черновик алгоритма и протестировали / профилировали его.
Бакуриу
@delnan: в моем случае все зависит от времени вычислений. Если для варианта C требуется х часов меньше, я бы потратил это время на то, чтобы алгоритмы работали дольше / снова. Я просто хочу выяснить (примерно), насколько медленнее будет Python - если это всего лишь пара часов, я, конечно, не буду использовать язык, с которым мне не по вкусу (вы можете испортить лучшие решения проблем с плохими реализациями: П).
CrazyFlyingCloseline
Право @ delnan в том, что Python, вероятно, достаточно быстр для многих вещей. Даже когда он медленнее, простота разработки, обслуживания и улучшения в будущем являются важными факторами, которые необходимо учитывать.
Мартино
"х часов"? Насколько большой это? Вы тестировали реализацию? У вас есть измерения? Вы профилировали реализацию? Или вы пытаетесь преждевременно оптимизировать решение?
S.Lott

Ответы:

115

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

Леннарт Регебро
источник
6
Конечно, это ничего не спасет, если вы не добавите кучу cdefобъявлений и не введете статическую типизацию (в противном случае вы просто манипулируете непрозрачными PyObject *вещами). И он никогда не будет работать так же быстро, как обычный C, потому что он обычно взаимодействует с Python (100% или более - только для простого числового кода, который вообще не взаимодействует с Python в течение большей части времени!). Но кроме этого, да, это может дать вам довольно быстрое ускорение.
7
@delnan: На самом деле, это что-то вас спасет. Самый чистый код Python будет быстрее после компиляции. Но да, с помощью cdefs и статической типизации вы действительно начинаете видеть различия. И взаимодействие с Python вы получаете во всех случаях, когда вы используете C из Python.
Леннарт Регебро
136

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

«инвестировать» здесь не то слово.

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

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

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

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

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

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


Институт Билла МакКинана Вана

С. Лотт
источник
15
Независимо от огромного количества баллов, я не вижу, как это отвечает на вопрос.
Аудрюс Мескаускас
29

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

ephemient
источник
3
+1 Одно из преимуществ Shed Skin - это вывод типов : если есть возможность угадывать типы переменных из потока программы, динамическая проверка типов исключается. Как правило, это приводит к сокращению кода на C ++, который на самом деле можно читать и компилировать в более быстрые программы.
Кисс Тао
1
Существует также транспортер Python → 11l → C ++ , который также является ограниченным компилятором Python для C ++, но он поддерживает некоторые функции Python, которые не поддерживаются в Shed Skin (например, вложенные функции / замыкания).
тав
17

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

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

seagull1089
источник
Этот проект гораздо более зрелый, чем другие подобные варианты. Забавно, что он создает двоичный файл с .exeрасширением для OSX, хотя это совершенно обычный исполняемый файл OSX Mach-O. Похоже , это может быть хорошей заменой pyinstaller, py2exe, py2appи т.д. --recurse-***Флаги важно установить правильно , хотя.
ccpizza
Nuitka великолепна, но созданный код на C / C ++ использует PyObject, который связывается с реализацией кода CPython-C. Он не производит идиоматический C-код.
Make42
8

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

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

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

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

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

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

boardrider
источник
6

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

Я лично использую 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, который я на самом деле не видел и не видел, является ли он полезным или просто бессмысленным. Удачи.

Надеюсь, это поможет.

jacktrader
источник
2
Я знаю, что это старый комментарий, но спасибо!
kfrncs
Нет проблем, я рад, что это было полезно.
Джектрейдер
Какое программное обеспечение вы используете для компиляции из интерпретации PyPy?
Василий Васьковский
Не конкретно PyPy, а только .py скрипты. Нуитка, если вы хотите "исполняемый файл C / C ++ или исходный код C / C ++" и PyInstaller, если вы просто хотите исполняемый файл (проще). Есть также py2exe, но у меня был меньший успех, хотя я уверен, что все улучшилось. PyInstaller также кроссплатформенный, не только для исполняемых файлов Windows (работает с Linux и Mac). Nuitka уникальна, потому что я думаю, что это единственный «компилятор», который возвращает вам пригодный исходный код, который вы теоретически можете оптимизировать дальше. Есть несколько других, таких как bbFreeze, cx_Freeze и py2app, но я их не пробовал. Удачи!
Джектрейдер
1
Я также обнаружил, что PyPy работает быстрее, чем Cython. В одном тесте я обнаружил, что PyPy имеет ту же скорость, что и версия программы на C ++ (сортировка вставкой).
Nv7
5

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

http://pythran.readthedocs.io/

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

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

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

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

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

paugier
источник
4

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

Ashley
источник
1
Похоже, что Py2C все еще не завершен. Он не обновлялся в течение нескольких лет, поэтому он может перестать существовать.
Андерсон Грин