Комментарии 26
Если ли какие-либо библиотеки, фреймворки для разработки модулей Python на C/C++?
пару раз использовал SWIG
Boost.Python, PySide(Qt идёт в комплекте если нужен), PyBind вообще их довольно много, но это всё для плюсов.
ctypes посмотрите - прекрасно и просто работает, совместим с numpy, несколькими комментариями ниже я ссылочки на гитхаб привел.
ctypes — это слишком низкоуровневая штука. Подходит, если уже есть сильная библиотека. Если же нужно написать сколько-нибудь сложный модуль и можно писать на C++, то лучше взять pybind11. Из того, чем пользовался, это самый удобный вариант.
С помощью этой библиотеки можно легко писать функции и классы, которые импортируются сразу как родные без какой-либо питоновской обвязки. Поддерживается очень много всего, есть удобная трансляция типов между языками.
Си нынче не в моде, нужно писать на Rust.
Кстате, а можно модули для питона писать на Rust?
Одна из самых развитых и протестированных в проде библиотек
Могу посоветовать серию статей (за моим авторством) на эту тему - https://dygalo.dev/blog/rust-for-a-pythonista-3/
В последней части там довольно много деталей о том как такие модули собирать, тестировать и дебажить.
Может просто с Python на Golang перейти и все?
Начать можно с написания C-Shared DLL на Go и вызова их из Python...
Конкретно на числах Фибоначчи @lru_cache
должно дать похожие результаты
Можно написать стандартную C библиотеку и подключить с помощью ctypes, который прекрасно поддерживается numpy. В реальности еще OpenMP нужен для распараллеливания по ядрам или OpenMPI по хостам. Вот пример такой библиотеки на гитхабе: https://github.com/mobigroup/gis-snippets/blob/master/geomed3d/geomed3dv3.py А еще можно заменить бинарные расширения на numba плюс dask или joblib, получив практически такую же скорость вычислений и распараллеливание. Пример на гитхабе: https://github.com/mobigroup/gis-snippets/blob/master/Synthetic%20Model%20Inversion/basic.ipynb
Сорри за первую ссылку, которая не кликабельна - чертов новый редактор комментариев то кусок текста убивает, то вот ссылки калечит, что на планшете, что на ноутбуке. Ссылка: https://github.com/mobigroup/gis-snippets/tree/master/geomed3d Тут лежит набор файлов .c и .h с библиотекой на C, питоновская «обертка» к модулю geomed3dv4.py и Jupyter notebook с примером geomed3dv4.ipynb
int для Фибоначчи - это несколько плохой пример. Он переполняется очень быстро, эти чуть больше 40 значений проще вообще тогда предвычислить и запихнуть в константы. Прямо в Питон.
Более того, даже unsigned long long рано или поздно может переполниться. И что тогда будете делать? А в Python собственная реализация int практически "резиновая". Да, это несёт накладные расходы. Тем не менее, я бы демонстрировал мощь Python C-API не на таком примере, а на примере POSIX threads. Это, пожалуй, самый большой камень в огороде Питона из-за GIL.
То есть, с помощью C-extension можно приделать модуль, который полностью отвечает требованиям внутреннего API Python (то есть, принимает и отдаёт в функциях Python-объекты), а внутри делает, например, так:
{
PyThreadState *_save;
Py_UNBLOCK_THREADS
do_some_jobs_in_threads();
Py_BLOCK_THREADS
}
Конечно, это не единственное, чего можно достичь. Среди дополнительных плюсов использования C-extension:
Более точное и аккуратное управление памятью, потому что int в интерпретаторе - это всегда громоздкая структура, а нам, например, требуется несколько 4-битных полей, которые можно плотно упаковать в структуру без выравнивания
Операции над примитивами в C всегда будут быстрее, чем операции над "примитивами" в интерпретаторе. Желающие могут убедиться, как всё сложно в интерпретаторе, попробовав реализовать 1-в-1 небольшую портянку на 50 строк Python-функции, но в виде C-extension и без использования сишных примитивов. Все эти PyCFunction, PyObject_GetAttribute, возня с INCREF/DECREF. В общем, всё то, что делал бы интерпретатор, только ручками. А затем скомпилировать и сравнить производительность. Выигрыш, если и будет, придётся в микроскоп разглядывать.
Некоторую часть вышеперечисленного (включая, кстати, работу с потоками исполнения) можно покрыть с помощью Cython. Но он далёк от совершенства и при этом генерирует очень грязный и избыточный код. Как прототип для MVP подойдёт, но потом всё равно оптимизировать и доводить до ума.
А вот чего действительно очень не хватает: это внятной документации по awaitable в C-API.
int в интерпретаторе - это всегда громоздкая структура, а нам, например, требуется несколько 4-битных полей, которые можно плотно упаковать в структуру без выравнивания
А какой практический смысл оптимизировать хранение одного int? Если у вас больше одного int (или не int) - есть массивы numpy, к этому блоку памяти можно получить прямой доступ из внешней библиотеки, с помощью cython и так далее. Выделяем память с помощью инициализации массива numpy, работаем с областью памяти из библиотеки и из питона читаем результат. Что вы тут оптимизировать собрались? Более того, с помощью numba можно практически такую же скорость получить для python кода.
Ну, во-первых, обычно, конечно же, надо не один int оптимизировать, а десятки или сотни всяких структур, указателей и указателей на указатели. Во-вторых, обработка из Питона результатов работы библиотеки превращается в боль, если мы говорим о хоть какой-то кросс-платформенности. На одной платформе без выравнивания не бывает, на другой указатели 32-битные, на третьей 64-битные, на четвертой еще какие-нибудь приколы. Всё это превращается в тонны if-else и подобных частоколов стреляющих в ногу ружей, и всё равно получается масса работы с int интерпретатора, а это постоянные boxing/unboxing.
Все намного проще, на самом деле. Вот как с помощью ctypes передать указатель на int массив numpy во внешнюю библиотеку: ndpointer(ctypes.c_int32, flags="C_CONTIGUOUS") и сами данные x.astype(ctypes.c_int32). В библиотеке на C объявляем этот аргумент функции как int32_t *x и работаем с этим массивом. Можно переданные массивы и читать и модифицировать, а потом в питоне прочитать измененную версию. Никаких проблем с кроссплатформенностью нет - нужно правильно указать типы данных, к примеру, int32. Если же вы привыкли везде писать int вместо int32, то вы сами стреляете себе в ногу. Аналогично, можно и с библиотекой на фортране легко работать. Ну, на фортране я сам давно уж не пишу, а вот читать код и подключать библиотеки порой приходится (особенно в языке R любят фортран библиотеки без единого комментария и с кучей «магии», для переноса научных вычислений на питон приходится разбираться).
Добрый вечер, сорри за оффтоп небольшой, подскажите, пожалуйста, как формулу в питоне представить в задаче 5? Очень степени смущают. Спасибо.
A = p * (1+r/n) ** nt
Но вы правы, это оффтоп. Для вопросов больше подходит https://qna.habr.com
С задачкой разобралась. Возник новый вопрос: почему не работает import turtle в pyscripter для python? выдает ошибку.
сразу вспомнился альтернативный вариант ускорения Python попроще - через Nim, nimpy и nimporter:
https://habr.com/ru/company/otus/blog/543332/
Мне кажется, сравнивать Python c Java глупо, ведь они работают практически одинаково.
Ускоряем код на Питоне с помощью расширений на Cи