Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Бинарные модули для Python

Бинарные модули для Python

Дмитрий Жильцов (ЦИАН, Системный Архитектор) @ Moscow Python Conf 2017
"Я расскажу про малоосвещенную тему – бинарные модули в питоне. В данном докладе речь будет идти о следующем:
1. Когда необходимы бинарные модули и зачем они нужны. В каких случаях их лучше использовать, а в каких нет. Как спроектировать грамотную архитектуру общения кода на Python с бинарным расширением.
2. Технологии и инструменты для разработки бинарных расширений. Минусы и плюсы каждого.
Доклад рассчитан на разработчиков, у которых есть потребность в разработке своих бинарных модулей, но не хватает опыта".
Видео: https://conf.python.ru/binarnye-moduli-dlya-python/.

Moscow Python Meetup
PRO

October 20, 2017
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. Б И Н А Р Н Ы Е М О Д У Л И
    В P Y T H O N

    View Slide

  2. О себе
    - Системный
    архитектор в ЦИАН
    - В разработке 10 лет

    View Slide

  3. О ЦИАН
    - 7 млн покупателей и
    арендаторов в месяц
    - 75% москвичей знают о нас
    - 8x разработка за 2014-2017

    View Slide

  4. Зачем нужны бинарные
    модули?

    View Slide

  5. Зачем нужны бинарные модули?
    • Python не так быстр как хочется
    • GIL – боль
    • Переиспользование логики из существующих библиотек
    • Скрытие исходников (спорно)

    View Slide

  6. Когда бинарные расширения
    действительно нужны?
    • Когда оптимизировали код и архитектуру, но
    производительности не хватает
    • Обильно используем multi threading для простых операций
    • Заведомо тяжелые операции
    • Образовалась стабильная логика работы модуля

    View Slide

  7. 5 золотых правил
    • Экспортировать функции
    • Использовать классы обертки
    • Нельзя напрямую передавать аргументы из Python в extension
    • Нужно дополнительно учитывать сборку мусора
    • Явно определять агрументы экспортируемой функции

    View Slide

  8. Архитектура бинарных расширений

    View Slide

  9. Технологии и Инструменты
    • Native C/C++ Extension

    View Slide

  10. Native C/C++ Extension
    Плюсы
    • Родная технология
    • Легко интегрируется в сборку
    проекта
    • Наибольшее кол-во
    документации
    • Позволяет создавать свои
    типы данных
    Минусы
    • Большой порог входа
    • Знание С
    • Boost.Python
    • Segmentation Fault :(
    • Сложности в Debug

    View Slide

  11. #include
    static PyObject*addList_add(PyObject* self, PyObject* args){
    PyObject * listObj;
    if (! PyArg_ParseTuple( args, "O", &listObj))
    return NULL;
    long length = PyList_Size(listObj);
    int i, sum =0;
    // Опустим реализацию
    return Py_BuildValue("i", sum);
    }

    View Slide

  12. for(i = 0; i < length; i++){
    // Получаем элемент из списка
    // он также Python-объект
    PyObject* temp = PyList_GetItem(listObj, i);
    // Мы знаем, что элемент это целое число
    // приводим его к типу C
    long long elem = PyLong_AsLong(temp);
    sum += elem;
    }

    View Slide

  13. // Документация
    static char addList_docs[] =
    "add( ): add all elements of the list\n";
    // Регистрируем функции модуля
    static PyMethodDef addList_funcs[] = {
    {"add", (PyCFunction)addList_add, METH_VARARGS,
    addList_docs},
    {NULL, NULL, 0, NULL}
    };

    View Slide

  14. static struct PyModuleDef moduledef = {
    PyModuleDef_HEAD_INIT,
    "addList",
    "addList example module",
    -1,
    addList_funcs,
    NULL,
    NULL,
    NULL,
    NULL
    };

    View Slide

  15. PyInit_addList(void){
    PyObject *module = PyModule_Create(&mdef);
    if (module == NULL)
    return NULL;
    PyModule_AddStringConstant(module,
    "__author__", “Bruse Lee");
    PyModule_AddStringConstant(module,
    "__version__", "1.0.0");
    return module;
    }

    View Slide

  16. Технологии и Инструменты
    • Native C/C++ Extension
    • SWIG

    View Slide

  17. SWIG
    Плюсы
    • Стабильная технология
    • Большое кол-во документации
    • Абстрагирует от привязки к
    Python
    Минусы
    • Долгая настройка
    • Знание С
    • Segmentation Fault :(
    • Сложности в Debug
    • Сложность интеграции в
    сборку проекта

    View Slide

  18. View Slide

  19. Технологии и Инструменты
    • Native C/C++ Extension
    • SWIG
    • Cython

    View Slide

  20. Cython
    Плюсы
    • Популярная технология
    • Довольно стабильно
    • Легко интегрируется в сборку
    проекта
    • Хорошая документация
    Минусы
    • Свой синтаксис
    • Знание С
    • Segmentation Fault :(
    • Сложности в Debug

    View Slide

  21. import cython
    class ComplexCalc(object):
    @cython.cfunc
    @cython.returns(cython.float)
    @cython.locals(x=cython.float, y=cython.float)
    def __cget_sum(self, x, y):
    return x+y
    complex.py

    View Slide

  22. Технологии и Инструменты
    • Native C/C++ Extension
    • SWIG
    • Cython
    • Ctypes

    View Slide

  23. CTypes
    Плюсы
    • Родная технология
    • Легко использовать в коде
    • Легко реализовать
    кросплатформенность
    • Можно использовать
    практически любой язык
    Минусы
    • Несет накладные расходы
    • Сложности в Debug

    View Slide

  24. from ctypes import *
    #load the shared object file
    adder = CDLL('./adder.so')
    #Calculate factorial
    res_int = adder.fact(4)
    print("Fact of 4 = " + str(res_int))

    View Slide

  25. Технологии и Инструменты
    • Native C/C++ Extension
    • SWIG
    • Cython
    • Ctypes
    • Rust

    View Slide

  26. Rust
    Плюсы
    • Безопасный язык
    • Мощные статические гарантии
    правильности поведения
    • Легко интегрируется в сборку
    проекта (PyO3)
    Минусы
    • Большой порог входа
    • Долгая настройка
    • Сложности в Debug
    • Документации мало
    • В некоторых случаях -
    накладные расходы

    View Slide

  27. #![feature(proc_macro)]
    #[macro_use] extern crate pyo3;
    use pyo3::prelude::*;
    /// Module documentation string 1
    #[py::modinit(_addList)]
    fn init(py: Python, m: &PyModule) -> PyResult {
    py_exception!(_addList, EmptyListError);
    /// Function documentation string
    #[pyfn(m, "run", args="*", kwargs="**")]
    fn run_py(_py: Python, args: &PyTuple, kwargs: Option) -> PyResult {
    run(args, kwargs)
    }
    #[pyfn(m, "add")]
    fn add(_py: Python, py_list: &PyList) -> PyResult {
    let mut sum : i32 = 0;
    match py_list.len() {
    /// Some code
    Ok(sum)
    }
    Ok(())
    }

    View Slide

  28. #[pyfn(m, "add", py_list="*")]
    fn add(_py: Python, py_list: &PyList) -> PyResult {
    match py_list.len() {
    0 =>Err(EmptyListError::new("List is empty")),
    _ => {
    let mut sum : i32 = 0;
    for item in py_list.iter() {
    let temp:i32 = match item.extract() {
    Ok(v) => v,
    Err(_) => {
    let err_msg: String = format!("List item {} is not int", item);
    return Err(ItemListError::new(err_msg))
    }
    };
    sum += temp;
    }
    Ok(sum)
    }
    }
    }

    View Slide

  29. Что выбрать в итоге?

    View Slide

  30. • Native C/C++ Extension
    • Знаем или не боимся изучить С
    • Важен результат а не скорость разработки
    • Минимум инструментария
    • SWIG
    • То же что и С-extension
    • Проблемы при сборке, но увеличивается скорость разработки
    • Cython
    • Новый язык
    • Малый порог входа
    • Скорость разработки
    • Ctypes
    • Быстро, дешево, сердито
    • Иногда вообще не надо пичего писать
    • Накладные расходы
    • Rust
    • Новый язык с наркоманским синтаксисом
    • Безопасность и гарантии
    • Не несет накладных расходов

    View Slide

  31. • https://github.com/zaabjuda/moscowpythonconf2017
    https://docs.python.org/3/extending/building.html
    • http://cython.org
    • https://docs.python.org/3.6/library/ctypes.html
    • http://www.swig.org
    • https://www.rust-lang.org/en-US/
    • https://github.com/PyO3
    • https://www.youtube.com/watch?v=5-WoT4X17sk
    • https://packaging.python.org/tutorials/distributing-packages/#platform-
    wheels

    View Slide

  32. ?

    View Slide