Есть ли преимущества использования интерфейса Python/C вместо Cython?
Я хочу расширить python и numpy, написав некоторые модули на C или С++, используя BLAS и LAPACK. Я также хочу иметь возможность распространять код как автономные библиотеки C/С++. Я бы хотел, чтобы в этих библиотеках использовался как float с одинарной, так и двойной точностью. Некоторые примеры функций, которые я напишу, представляют собой сопряженный градиент для решения линейных систем или ускоренных методов первого порядка. Некоторым функциям необходимо будет вызвать функцию Python из кода C/С++.
Поиграв немного с API Python/C и API Numpy/C, я обнаружил, что многие люди выступают за использование Cython вместо этого (см. например этот вопрос или этот). Я не специалист по Cython, но кажется, что для некоторых случаев вам все равно нужно использовать API Numpy/C и знать, как это сделать работает. Учитывая тот факт, что у меня уже есть (немного) знания о API Python/C и ни о CBOTON, мне было интересно, имеет ли смысл продолжать использовать Python/C API, и если использование этого API имеет некоторые преимущества перед Cython, В будущем я, конечно же, буду развивать некоторые вещи, не связанные с численными вычислениями, поэтому этот вопрос не только о numpy. Одна из вещей, которые мне нравятся в API Python/C, заключается в том, что я изучаю некоторые вещи о том, как работает интерпретатор Python.
Спасибо.
Ответы
Ответ 1
Во-первых, есть один момент в вашем вопросе, который я не получаю:
[...] также хотят иметь возможность распространять код как автономные библиотеки C/С++. [...] Некоторые функции должны будут вызвать функцию Python из кода C/С++.
Как это должно работать?
Далее, что касается вашего фактического вопроса, есть, конечно, преимущества использования API Python/C напрямую:
-
Скорее всего, вы более знакомы с написанием кода на C, чем написанием кода Cython.
-
Написание кода на C дает вам максимальный контроль. Чтобы получить такую же производительность от кода Cython, как и от эквивалентного кода C, вам нужно быть очень осторожным. Вам не только нужно будет объявить типы всех переменных, вам также необходимо будет установить некоторые флаги надлежащим образом - всего один пример проверка границ. Вам понадобятся интимные знания о том, как Cython работает, чтобы получить лучшую производительность.
-
Код Cython зависит от Python. Представляется, что не стоит писать код, который также должен быть распространен как автономная библиотека C в Cython
Ответ 2
Текущий "верхний ответ" звучит слишком сильно, как FUD в моих ушах. Во-первых, не сразу очевидно, что Средний разработчик напишет более быстрый код на C, чем то, что NumPy + Cython дает вам в любом случае. Напротив, время, затрачиваемое на то, чтобы заставить C-код правильно работать в среде Python, обычно намного лучше вписывается в быстрый прототип в Cython, сравнивая его, оптимизируя его, переписывая его быстрее, сравнивая его снова, а затем решив, есть ли в нем что-то, что действительно требует 5-10% большей производительности, которую вы можете или не можете получить от перезаписи 2% кода в ручном настройке C и вызова его из вашего кода Cython.
Я пишу библиотеку в Cython, которая в настоящее время имеет около 18 тыс. строк кода Cython, которые переводят почти на 200 тыс. строк кода C. Однажды мне удалось получить ускорение почти на 25% за пару очень важных функций внутреннего базового уровня, введя в правильные места около 20 строк кода C с ручной настройкой. Мне потребовалось пару часов, чтобы переписать и оптимизировать эту крошечную часть. Это поистине ничто по сравнению с огромным количеством времени, которое я сохранил, не записывая (и не поддерживая) библиотеку на равнине C. В первую очередь.
Даже если вы знаете C намного лучше, чем Cython, если вы знаете Python и C, вы научитесь Cython так быстро, что это стоит инвестиций в любом случае, особенно когда вы находитесь в цифрах. 80-95% кода, который вы пишете, будут настолько полезны, чтобы быть написанным на языке высокого уровня, что вы можете спокойно отложить назад и инвестировать половину времени, которое вы сохранили, в создание своего кода так же быстро, как если бы вы его написали на низкоуровневом языке.
При этом ваш комментарий о том, что вы хотите "иметь возможность распространять код как автономные библиотеки C/С++", является веской причиной придерживаться простого C/С++. Cython всегда зависит от CPython, который является довольно зависимым. Однако использование простого C/С++ (за исключением интерфейса Python) не позволит вам использовать NumPy, так как это также зависит от CPython. Поэтому, как обычно, когда вы пишете что-то на C, вам нужно будет сделать много работы, прежде чем вы перейдете к фактической функциональности. Вы должны серьезно подумать об этом дважды, прежде чем начинать эту работу.
Ответ 3
Основным недостатком API Python/C является то, что он может быть очень медленным, если он используется во внутреннем цикле. Я вижу, что вызов функции Python приводит к переходу 80-160x при вызове эквивалентной функции С++.
Если это не мешает вашему коду, вам выгодно писать некоторые куски кода в Python, иметь доступ к библиотекам Python, поддерживать обратные вызовы, написанные непосредственно на Python. Это также означает, что вы можете внести некоторые изменения без перекомпиляции, упрощая создание прототипов.