Разработка прототипа с кодом Python перед компиляцией

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

1 - 7f / 10
1 - 7 / 10f

или:

1 - 7d / 10
1 - 7 / 10d
21
задан Mike Pennington 25 November 2011 в 12:00
поделиться

7 ответов

Наконец, вопрос, на который я действительно могу дать ценный ответ :).

Я исследовал f2py, boost.python, swig, cython и pyrex для своей работы (доктор философии в области оптических методов измерения). Я широко использовал swig, некоторые из boost.python, а также pyrex и cython. Я также использовал ctypes. Это моя поломка:

Заявление об ограничении ответственности : Это мой личный опыт. Я не участвую ни в одном из этих проектов.

swig: плохо работает с c ++. Так и должно быть, но на этапе связывания названия проблем с искажением имен были для меня большой головной болью в Linux и Mac OS X. Если у вас есть код C и вы хотите, чтобы он был связан с python, это хорошее решение. Я упаковал GTS для своих нужд, и мне нужно было написать в основном разделяемую библиотеку C, к которой я мог бы подключиться. Я бы не рекомендовал это.

Ctypes: Я написал оболочку libdc1394 (библиотека камеры IEEE), используя ctypes, и это было очень несложно. Вы можете найти код на https://launchpad.net/pydc1394 . Преобразование заголовков в код Python - это большая работа, но тогда все работает надежно. Это хороший способ, если вы хотите связать внешнюю библиотеку. Ctypes также находится в stdlib Python, поэтому каждый может сразу же использовать ваш код. Это также хороший способ быстро поиграться с новой библиотекой в ​​python. Я могу рекомендовать его для взаимодействия с внешними библиотеками.

Boost.Python : Очень приятно. Если у вас уже есть собственный код C ++, который вы хотите использовать в Python, сделайте это. Таким образом очень легко преобразовать структуры классов C ++ в структуры классов Python. Я рекомендую его, если у вас есть код C ++, который вам нужен на Python.

Pyrex / Cython: Используйте Cython, а не Pyrex. Период. Cython более продвинутый и более приятный в использовании. В настоящее время я делаю с cython все, что раньше делал с SWIG или Ctypes. Это также лучший способ, если у вас слишком медленный код Python. Процесс абсолютно фантастический: вы конвертируете свои модули python в модули cython, создаете их и продолжаете профилировать и оптимизировать, как будто это все еще был python (без смены инструментов). Затем вы можете применить столько (или так мало) кода C, смешанного с вашим кодом Python. Это намного быстрее, чем необходимость переписывать целые части вашего приложения на C; вы только переписываете внутренний цикл.

Тайминги : ctypes имеет самые высокие накладные расходы на вызов (~ 700 нс), за ним следует boost.python (322 нс), а затем непосредственно swig (290 нс). Cython имеет самые низкие накладные расходы на вызовы (124 нс) и лучшую обратную связь, на которую он тратит время (поддержка cProfile!). Числа взяты из моего ящика, вызывающего тривиальную функцию, возвращающую целое число из интерактивной оболочки; поэтому накладные расходы на импорт модуля не рассчитываются по времени, учитываются только накладные расходы на вызов функции. Поэтому проще и продуктивнее всего быстро получить код Python путем профилирования и использования cython.

Резюме : Для решения вашей проблемы используйте Cython;). Я надеюсь, что это краткое изложение будет полезно для некоторых людей. Я с радостью отвечу на любой оставшийся вопрос.


Edit : Я забыл упомянуть: для числовых целей (то есть для подключения к NumPy) используйте Cython; у них есть поддержка для этого (потому что они в основном разрабатывают cython для этой цели). Так что это должен быть еще один +1 для вашего решения.

Числа взяты из моего ящика, вызывающего тривиальную функцию, возвращающую целое число из интерактивной оболочки; поэтому накладные расходы на импорт модуля не рассчитываются по времени, учитываются только накладные расходы на вызов функции. Поэтому проще и продуктивнее всего быстро получить код Python путем профилирования и использования cython.

Резюме : Для решения вашей проблемы используйте Cython;). Я надеюсь, что это краткое изложение будет полезно для некоторых людей. Я с радостью отвечу на любой оставшийся вопрос.


Edit : Я забыл упомянуть: для числовых целей (то есть для подключения к NumPy) используйте Cython; у них есть поддержка (потому что они в основном разрабатывают cython для этой цели). Так что это должен быть еще один +1 для вашего решения.

Числа взяты из моего ящика, вызывающего тривиальную функцию, возвращающую целое число из интерактивной оболочки; поэтому накладные расходы на импорт модуля не рассчитываются по времени, учитываются только накладные расходы на вызов функции. Поэтому проще и продуктивнее всего быстро получить код Python путем профилирования и использования cython.

Резюме : Для решения вашей проблемы используйте Cython;). Я надеюсь, что это краткое изложение будет полезно для некоторых людей. Я с радостью отвечу на любой оставшийся вопрос.


Edit : Я забыл упомянуть: для числовых целей (то есть для подключения к NumPy) используйте Cython; у них есть поддержка для этого (потому что они в основном разрабатывают cython для этой цели). Так что это должен быть еще один +1 для вашего решения.

Поэтому проще и продуктивнее всего быстро получить код Python путем профилирования и использования cython.

Резюме : Для решения вашей проблемы используйте Cython;). Я надеюсь, что это краткое изложение будет полезно для некоторых людей. Я с радостью отвечу на любой оставшийся вопрос.


Edit : Я забыл упомянуть: для числовых целей (то есть для подключения к NumPy) используйте Cython; у них есть поддержка (потому что они в основном разрабатывают cython для этой цели). Так что это должен быть еще один +1 для вашего решения.

Поэтому проще и продуктивнее всего быстро получить код Python путем профилирования и использования cython.

Резюме : Для решения вашей проблемы используйте Cython;). Я надеюсь, что это краткое изложение будет полезно для некоторых людей. Я с радостью отвечу на любой оставшийся вопрос.


Edit : Я забыл упомянуть: для числовых целей (то есть для подключения к NumPy) используйте Cython; у них есть поддержка для этого (потому что они в основном разрабатывают cython для этой цели). Так что это должен быть еще один +1 для вашего решения.

у них есть поддержка для этого (потому что они в основном разрабатывают cython для этой цели). Так что это должен быть еще один +1 для вашего решения.

у них есть поддержка для этого (потому что они в основном разрабатывают cython для этой цели). Так что это должен быть еще один +1 для вашего решения.

35
ответ дан 29 November 2019 в 06:46
поделиться

Я не использовал БОЛЬШОЙ ГЛОТОК или SIP, но я нахожу запись обертками Python с boost.python, чтобы быть очень мощным и относительно простым в использовании.

я не ясен на том, что Ваши требования для передачи типов между C/C++ и Python, но можно сделать это легко или представлением типа C++ к Python, или при помощи дженерика повышение:: Python:: объект аргумент Вашему API C++. Можно также зарегистрировать преобразователи для автоматического преобразования типов Python в типы C++ и наоборот.

при планировании использования boost.python, учебное руководство является хорошим местом для запуска.

я реализовал что-то несколько подобное тому, в чем Вы нуждаетесь. У меня есть функция C++, которая принимает функцию Python и изображение как аргументы, и применяет функцию Python к каждому пикселю в изображении.

Image* unary(boost::python::object op, Image& im)
{
    Image* out = new Image(im.width(), im.height(), im.channels());
    for(unsigned int i=0; i<im.size(); i++)
    {
        (*out)[i] == extract<float>(op(im[i]));
    }
    return out;
}

В этом случае, Изображение является объектом C++, представленным Python (изображение с пикселями плавающими), и op является Python определенная функция (или действительно любой объект Python с _ _ call_ _ атрибут). Можно тогда использовать эту функцию следующим образом (принимающий унарный, расположен в названном изображении, которое также содержит Изображение и функцию загрузки):

import image
im = image.load('somefile.tiff')
double_im = image.unary(lambda x: 2.0*x, im)

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

10
ответ дан Moe 29 November 2019 в 06:46
поделиться

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

Это обеспечит непосредственное отображение от Вашего кода прототипа Python до возможного скомпилированного кода и позволит Вам использовать ctypes легко и избежать целого набора головных болей.

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

, Если Вы действительно хотите использовать более сложные структуры данных или изменить передаваемые аргументы, БОЛЬШОЙ ГЛОТОК или , стандартный интерфейс C-расширения Python позволит Вам сделать то, что Вы хотите, но с некоторой суммой стычки.

Для того, что Вы делаете, можно также хотеть проверить NumPy, который мог бы сделать часть работы, которую Вы захотите продвинуть к C, а также предложению некоторая дополнительная справка в движущихся данных назад и вперед между Python и C.

6
ответ дан twasbrillig 29 November 2019 в 06:46
поделиться

f2py (часть numpy) является более простой альтернативой БОЛЬШОМУ ГЛОТКУ и boost.python для обертывания кода перемалывания чисел C/Fortran.

4
ответ дан jfs 29 November 2019 в 06:46
поделиться

Python довольно либерален в разрешении функций, функторов, объекты, которые будут переданы функциям и методам, тогда как я подозреваю, то же не верно для, говорят C или Фортран.

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

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

0
ответ дан David Locke 29 November 2019 в 06:46
поделиться

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

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

второй самый легкий путь состоит в том, чтобы записать модуль Python в C и затем вызвать функции в том модуле. Можно передать что-либо, что Вы хотите к этим функциям C, не имея необходимость переходить через любые обручи. И легко вызвать функции Python или методы от этих функций C, как описано здесь: https://docs.python.org/extending/extending.html#calling-python-functions-from-c

у меня нет достаточного опыта с БОЛЬШИМ ГЛОТКОМ для предложения интеллектуального комментария. И в то время как возможно сделать, вещам нравится передача, которой пользовательский Python возражает против функций C через ctypes, или определить новые классы Python в C, эти вещи являются раздражающими и подробными, и я рекомендую проявить один из двух подходов, описанных выше.

1
ответ дан twasbrillig 29 November 2019 в 06:46
поделиться

In addition to the tools above, I can recommend using Pyrex (for creating Python extension modules) or Psyco (as JIT compiler for Python).

0
ответ дан 29 November 2019 в 06:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: