Есть ли преимущества использования интерфейса Python / C вместо Cython? - PullRequest
42 голосов
/ 19 апреля 2011

Я хочу расширить python и numpy, написав несколько модулей на C или C ++, используя BLAS и LAPACK.Я также хочу иметь возможность распространять код в виде отдельных библиотек C / C ++.Я хотел бы, чтобы эти библиотеки использовали как одинарную, так и двойную точность с плавающей точкой.Некоторые примеры функций, которые я напишу, являются сопряженными градиентами для решения линейных систем или ускоренными методами первого порядка.Некоторые функции должны будут вызывать функцию Python из кода C / C ++.

Немного поиграв с API Python / C и API Numpy / C, я обнаружил, что многие люди вместо этого рекомендуют использовать Cython.(см., например, этот вопрос или этот вопрос ).Я не эксперт по Cython, но кажется, что для некоторых случаев вам все еще нужно использовать API Numpy / C и знать, как он работает.Учитывая тот факт, что у меня уже есть (некоторые небольшие) знания о API Python / C и ничего о Cython, мне было интересно, имеет ли смысл продолжать использовать API Python / C, и если использование этого API имеет некоторые преимущества перед Cython,В будущем я, конечно, разработаю некоторые вещи, не связанные с числовыми вычислениями, так что этот вопрос касается не только кучи.В Python / C API мне нравится то, что я узнаю кое-что о том, как работает интерпретатор Python.

Спасибо.

Ответы [ 3 ]

76 голосов
/ 22 апреля 2011

Текущий «лучший ответ» звучит слишком похоже на FUD в моих ушах. С одной стороны, не сразу очевидно, что средний разработчик написал бы более быстрый код на C, чем в любом случае дает вам NumPy + Cython. Напротив, время, необходимое для того, чтобы даже заставить необходимый C-код работать правильно в среде Python, обычно гораздо лучше инвестируется в написание быстрого прототипа на Cython, его сравнительный анализ, оптимизацию, переписывание более быстрым способом, сравнительный анализ снова и затем , решая, есть ли в нем что-либо, что действительно требует на 5-10% большей производительности, которую вы можете получить, а можете и не получить, переписав 2% кода в вручную настроенном C и вызвав его из ваш код Cython.

Я пишу библиотеку на Cython, которая в настоящее время содержит около 18K строк кода Cython, которые переводят почти в 200K строк кода C. Однажды мне удалось добиться ускорения почти на 25% для пары очень важных функций внутреннего базового уровня, введя около 20 строк вручную настроенного кода C в нужных местах. Мне потребовалось несколько часов, чтобы переписать и оптимизировать эту крошечную часть. Это действительно ничто по сравнению с огромным количеством времени, которое я сэкономил, не написав (и не поддерживая) библиотеку на простом C, во-первых.

Даже если вы знаете C намного лучше, чем Cython, если вы знаете Python и C, вы выучите Cython так быстро, что в любом случае это стоит вложений, особенно когда вы работаете с цифрами. 80-95% кода, который вы пишете, получат столько пользы от написания на языке высокого уровня, что вы можете спокойно откладывать и тратить половину времени, которое вы сэкономили, на создание кода так же быстро, как если бы вы его написали. на языке низкого уровня прямо сейчас.

Тем не менее, ваш комментарий о том, что вы хотите "иметь возможность распространять код в виде автономных библиотек C / C ++", является веской причиной придерживаться простого C / C ++. Cython всегда зависит от CPython, который является довольно зависимым. Однако использование простого C / C ++ (за исключением интерфейса Python) также не позволит вам воспользоваться NumPy, поскольку это также зависит от CPython. Поэтому, как обычно, когда пишете что-то на C, вам придется проделать большую работу, прежде чем вы перейдете к реальной функциональности. Вы должны серьезно подумать об этом дважды, прежде чем начинать эту работу.

8 голосов
/ 20 апреля 2011

Во-первых, есть один вопрос в вашем вопросе, который я не понимаю:

[...] также хочет иметь возможность распространять код в виде отдельных библиотек C / C ++.[...] Некоторым функциям потребуется вызывать функцию Python из кода C / C ++.

Как это должно работать?

Далее, что касается вашего фактического вопросабезусловно, есть преимущества использования Python / C API напрямую:

  • Скорее всего, вы более знакомы с написанием кода C, чем с написанием кода Cython.

  • Написание кода на C дает вам максимальный контроль.Чтобы получить ту же производительность из кода Cython, что и из эквивалентного кода C, вам нужно быть очень осторожным.Вам не только нужно будет обязательно объявлять типы всех переменных, вы также должны будете правильно установить некоторые флаги - только один пример - проверка границ .Вам понадобятся глубокие знания о том, как работает Cython, чтобы добиться максимальной производительности.

  • Код Cython зависит от Python.Похоже, не стоит писать код, который также должен распространяться как автономная библиотека C на Cython

0 голосов
/ 19 апреля 2011

Основным недостатком Python / C API является то, что он может быть очень медленным, если он используется во внутреннем цикле. Я вижу, что вызов функции Python требует в 80-160 раз больше, чем вызов эквивалентной функции C ++.

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

...