SlideShare uma empresa Scribd logo
1 de 53
Baixar para ler offline
Python и Cython
    Оптимизация и стыковка с C



Александр Шигин, shigin@rambler-co.ru
           Rambler, 2010
Python   удобно
Python удобно
  ... но не быстро
•   динамический язык;
•   байт код без компиляции;
•   GC на счетчике ссылок;
•   Global Interpretor Lock;
•   если что-то работает медленнее
    python’а, это не значит что
    python быстрый.
•   динамический язык;
•   байт код без компиляции;
•   GC на счетчике ссылок;
•   Global Interpretor Lock;
•   если что-то работает медленнее
    python’а, это не значит что
    python быстрый.
Еще про ref-counting

•   процессы плохая замена
    тредам;
•   не работает Copy–on–Write;
•   мы не можем легко
    распараллелить программу,
    когда у нас много данных.
...
d = d i c t ( ( i , ’ t h e s t r i n g w i t h %d ’ % i )
                for i in x r a n g e ( 5 0 0 ∗ 1 0 0 0 ) )
time . s l e e p (10)
s y s . s t d e r r . w r i t e ( ’ about t o f o r k . . .  n ’ )
os . f o r k ( )

f or i , k in d . i t e r i t e m s ( ) :
     pass
time . s l e e p (10)
C   не так удобно
C       не так удобно
    ... но достаточно
         быстро
C + Python = ???
C + Python =
   медленнее C
C + Python =
   медленнее C
   а удобно?
Python
def sum_th(lst):
    result = 0
    for i in lst:        #!
        result += i.th   #!!!111
    return result
Pure C
long sum_th(const struct with_th_t *all,
        size_t size) {
    long result = 0;
    size_t i;
    for (i = 0; i < size; ++i) {
        result += all[i].th;
    }
    return result;
}
Модуль на C
while ((item = PyIter_Next(iterator)) != NULL) {
    PyObject *field = PyObject_GetAttr(
        item, interned_th);
    if (field == NULL) {
        Py_DECREF(result);
        Py_DECREF(item);
        return NULL;
    }
    PyObject *nw = PyNumber_Add( result, field);
    Py_DECREF(result);
    ...
Python


def sum_th(lst):
    result = 0
    for i in lst:        #!
        result += i.th   #!!!111
    return result
Осторожно,
benchmark!
Итого
      Python Pure C C module
строк   5      7       28

•   На реальном коде разница будет
    меньше!
•   Но разница будет.
???
Долго писать:
 • много кода;

 • сложность отладки.



Потеря скорости:
 • boxing/unboxing.
boxing/unboxing
                  PyInt_FromSize_t




PyInt_FromLong                 PyLong_FromSize_t




  fill_free_list             _PyLong_FromByteArray




                                 _PyLong_New
boxing/unboxing
           PyInt_AsLong




 PyInt_Check         tp_as_number




PyInt_AS_LONG         PyInt_Check




         PyInt_AS_LONG          PyLong_Check




                                PyLong_AsLong
Cython

•   страшная смесь Python’а и C;
•   понимает подмножество Python;
•   генерирует C-код;
•   def/cdef/cpdef.
•   lxml, SciPy, ...
•   читайте FAQ;
•   используйте cdef;
•   не *q = 0, а q[0] = 0;
•   не путайте float и double;
•   cdef для переменных, которые
    участвуют в циклах;
•   cython -a.
shlex.split
•   Ускорим простую программу
    в XX раз.
•   За 15 минут.
•   Сейчас это займет куда меньше
    времени.
Задача
127.0.0.1 "it’s query" "client id" 12.0 ...

  •   str.split не сработает: некоторые
      поля окружены кавычками.
  •   25 миллионов строк в день.
  •   680 миллионов строк в месяц.
Что имеем
sm = 0.0
cnt = 0
for line in sys.stdin:
    split = shlex.split(line)
    try:
         sm += float(split[12])
         cnt += 1
    except ValueError:
         pass
Что имеем
Используем стандартный shlex.split и файл в 900
строк.

       SUMMARY
real time: 0.870 [ 0.875 +-0.004]        0.878
sys time: 0.004 [ 0.007 +-0.002]         0.008
user time: 0.844 [ 0.860 +-0.014]        0.868

≈ 1 мс на строку.
≈ 7 часов на дневной лог
Что имеем
Своя, очень простая реализация. Тот же файл.

       SUMMARY
real time: 0.603 [ 0.614 +-0.009]       0.621
sys time: 0.000 [ 0.001 +-0.002]        0.004
user time: 0.596 [ 0.601 +-0.006]       0.608

≈ 0.7 мс на строку.
≈ 5 часов на дневной лог
Что имеем

Та же реализация, но откомпилированная в
cython. Тот же файл.

       SUMMARY
real time: 0.650 [ 0.664 +-0.013]      0.675
sys time: 0.000 [ 0.000 +-0.000]       0.000
user time: 0.640 [ 0.655 +-0.014]      0.668
cython -a
Уберем Python API
Уберем Python API
Time table
      время
      0.603   исходный код
      0.532   объявить типы
      0.151   cdef class
      0.029   char *
≈ 14 минут на дневной лог файл.
Cython vs ...

•   boost::python;
•   SWIG;
•   expy;
•   ...
Проблема boxing/unboxing

1   Найдем функцию, что занимает
    >50% времени.
2   Перепишем её на C.
3   ???
Проблема boxing/unboxing

1   Найдем функцию, что занимает
    >50% времени.
2   Перепишем её на C.
3   ???
4   Нет профита.
Профилирование
Подход ускорения через
профилирование порочен:
  • не надо думать, что остальная

    программа ускорится;
  • что делать, если нет очевидного

    медленного места?
Кроме этого
•   на каждый вызов функции надо
    преобразовывать данные;
•   в вырожденных случаях, это
    будет дольше самой функции;
•   мы вынуждены переписывать
    все места, где мы вызываем
    нашу функцию.
Решение

•   частичная оптимизация;
•   cpdef;
•   перетаскивание функционала в
    cython, а потом в C;
•   это не панацея.
Сложные данные

Как работать с данными из C и
Python.
 • proxy/wrapper;

 • копия.
Копирование vs proxy
proxy:
  • каждый раз преобразовывать;

  • но есть кеш объектов;

  • код на C работает быстро;

  • это тот код, который нас

    интересует.
Копирование vs proxy

Копирование:
 • идеально для неизменяемых

   объектов;
 • но требует много памяти;

 • fork...
Еще раз про GIL
GIL это не
 проблема
GIL

•   он нужен, пока мы работаем с
    python данными;
•   в критичных местах, мы не
    работаем с python данными;
•   мы можем его отпустить.
proxy: запрет создания из
            python
cdef class _Q:
    def __cinit__(self, ....):
        ....

    def __init__(self, ....):
        raise TypeError, ""

cpdef _Q Q(....):
    cdef _Q q = _Q.__new__(_Q)
    return q
Кеширование объектов
•   попробуйте id;
•   попробуйте перенумеровать в
    зависимости от частоты;
•   убедитесь, что у вас
    неизменяемые типы;
•   треды...
Кеширование прокси
    объектов
Python container    a[0]    a[1]   ...   a[n]




                 C struct    ...   void *extra




     container     struct   Python proxy
Кеширование прокси
          объектов
          Python container     a[0]     a[1]   ...   a[n]



                             C struct    ...   void *extra
 __getitem__



Python proxy   container   struct     next           Python proxy   ...
Кеширование прокси
         объектов
cdef _Point point_wrap(point_t *x):
    cdef _Point result
    if x.extra != NULL:
        return <_Point>x.extra
    result = _Point.__new__(_Point)
    result.inner = x
    if is_common_point(x):
        print ’cache’
        x.extra = <void *>result
    return result
Мои выводы

•   python это удобно;
•   С это быстро;
•   cython объединяет;
•   все будет хорошо.
Благодарю за
  внимание

  shigin@rambler-co.ru
 friendfeed.com/shigin
Вопросы?

 shigin@rambler-co.ru
friendfeed.com/shigin

Mais conteúdo relacionado

Mais procurados

разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3Eugeniy Tyumentcev
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksMikhail Kurnosov
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаSergey Platonov
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Platonov Sergey
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Sergey Platonov
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 
Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]
Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]
Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]Python Meetup
 
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Mikhail Kurnosov
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines Sergey Zubkov
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Yandex
 
Введение в потоки питона
Введение в потоки питонаВведение в потоки питона
Введение в потоки питонаAndrey Niahajchyk
 
Intel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиIntel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиTatyanazaxarova
 
"Внутренности" CPython, часть II
"Внутренности" CPython, часть II"Внутренности" CPython, часть II
"Внутренности" CPython, часть IIPython Meetup
 
разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2Eugeniy Tyumentcev
 
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияAlexey Paznikov
 
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...WebCamp
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPMikhail Kurnosov
 
JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)
JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)
JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)aragozin
 
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаАндрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаSergey Platonov
 

Mais procurados (20)

разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building BlocksЛекция 8: Многопоточное программирование: Intel Threading Building Blocks
Лекция 8: Многопоточное программирование: Intel Threading Building Blocks
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
Александр Тарасенко, Использование python для автоматизации отладки С/C++ код...
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]
Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]
Python AST / Николай Карелин / VPI Development Center [Python Meetup 27.03.15]
 
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
 
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
 
Введение в потоки питона
Введение в потоки питонаВведение в потоки питона
Введение в потоки питона
 
Intel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибкамиIntel IPP Samples for Windows - работа над ошибками
Intel IPP Samples for Windows - работа над ошибками
 
"Внутренности" CPython, часть II
"Внутренности" CPython, часть II"Внутренности" CPython, часть II
"Внутренности" CPython, часть II
 
разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2
 
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программированияПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
 
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
 
Лекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMPЛекция 6. Стандарт OpenMP
Лекция 6. Стандарт OpenMP
 
JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)
JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)
JIT-компиляция в виртуальной машине Java (HighLoad++ 2013)
 
Андрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кодаАндрей Карпов, Приватные байки от разработчиков анализатора кода
Андрей Карпов, Приватные байки от разработчиков анализатора кода
 

Semelhante a Python и Cython

Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийAndrey Akinshin
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Pythonru_Parallels
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на PythonCodeFest
 
Управление памятью в CPython
Управление памятью в CPythonУправление памятью в CPython
Управление памятью в CPythonAnton Patrushev
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1m2rus
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыcorehard_by
 
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНСit-people
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#Andrey Karpov
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++Andrey Karpov
 
Денис Колодин: Low-latency и soft-realtime на Python
Денис Колодин: Low-latency и soft-realtime на PythonДенис Колодин: Low-latency и soft-realtime на Python
Денис Колодин: Low-latency и soft-realtime на Pythonit-people
 
ekbpy'2012 - Марк Коренберг - Системное программирование на Питоне
ekbpy'2012 - Марк Коренберг - Системное программирование на Питонеekbpy'2012 - Марк Коренберг - Системное программирование на Питоне
ekbpy'2012 - Марк Коренберг - Системное программирование на Питонеit-people
 
Борзунов Александр, Cpmoptimize
Борзунов Александр, CpmoptimizeБорзунов Александр, Cpmoptimize
Борзунов Александр, CpmoptimizeDarya Zubova
 
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...Alexander Borzunov
 
Про асинхронное сетевое программирование
Про асинхронное сетевое программированиеПро асинхронное сетевое программирование
Про асинхронное сетевое программированиеPython Meetup
 
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)Ontico
 
SECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли UnitySECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли UnitySECON
 
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Fwdays
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаAndrey Karpov
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один goBadoo Development
 

Semelhante a Python и Cython (20)

Поговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложенийПоговорим о микрооптимизациях .NET-приложений
Поговорим о микрооптимизациях .NET-приложений
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Python
 
Сверхоптимизация кода на Python
Сверхоптимизация кода на PythonСверхоптимизация кода на Python
Сверхоптимизация кода на Python
 
Управление памятью в CPython
Управление памятью в CPythonУправление памятью в CPython
Управление памятью в CPython
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1Основы и применение статического анализа кода при разработке лекция 1
Основы и применение статического анализа кода при разработке лекция 1
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
 
Эффективный C++
Эффективный C++Эффективный C++
Эффективный C++
 
Денис Колодин: Low-latency и soft-realtime на Python
Денис Колодин: Low-latency и soft-realtime на PythonДенис Колодин: Low-latency и soft-realtime на Python
Денис Колодин: Low-latency и soft-realtime на Python
 
ekbpy'2012 - Марк Коренберг - Системное программирование на Питоне
ekbpy'2012 - Марк Коренберг - Системное программирование на Питонеekbpy'2012 - Марк Коренберг - Системное программирование на Питоне
ekbpy'2012 - Марк Коренберг - Системное программирование на Питоне
 
Борзунов Александр, Cpmoptimize
Борзунов Александр, CpmoptimizeБорзунов Александр, Cpmoptimize
Борзунов Александр, Cpmoptimize
 
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...
Автоматическая оптимизация алгоритмов с помощью быстрого возведения матриц в ...
 
Про асинхронное сетевое программирование
Про асинхронное сетевое программированиеПро асинхронное сетевое программирование
Про асинхронное сетевое программирование
 
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
 
SECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли UnitySECON'2016. Чубарь Алексей, Мобильные грабли Unity
SECON'2016. Чубарь Алексей, Мобильные грабли Unity
 
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
 
Опыт разработки статического анализатора кода
Опыт разработки статического анализатора кодаОпыт разработки статического анализатора кода
Опыт разработки статического анализатора кода
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
 

Python и Cython

  • 1. Python и Cython Оптимизация и стыковка с C Александр Шигин, shigin@rambler-co.ru Rambler, 2010
  • 2. Python удобно
  • 3. Python удобно ... но не быстро
  • 4. динамический язык; • байт код без компиляции; • GC на счетчике ссылок; • Global Interpretor Lock; • если что-то работает медленнее python’а, это не значит что python быстрый.
  • 5. динамический язык; • байт код без компиляции; • GC на счетчике ссылок; • Global Interpretor Lock; • если что-то работает медленнее python’а, это не значит что python быстрый.
  • 6. Еще про ref-counting • процессы плохая замена тредам; • не работает Copy–on–Write; • мы не можем легко распараллелить программу, когда у нас много данных.
  • 7. ... d = d i c t ( ( i , ’ t h e s t r i n g w i t h %d ’ % i ) for i in x r a n g e ( 5 0 0 ∗ 1 0 0 0 ) ) time . s l e e p (10) s y s . s t d e r r . w r i t e ( ’ about t o f o r k . . . n ’ ) os . f o r k ( ) f or i , k in d . i t e r i t e m s ( ) : pass time . s l e e p (10)
  • 8. C не так удобно
  • 9. C не так удобно ... но достаточно быстро
  • 10. C + Python = ???
  • 11. C + Python = медленнее C
  • 12. C + Python = медленнее C а удобно?
  • 13. Python def sum_th(lst): result = 0 for i in lst: #! result += i.th #!!!111 return result
  • 14. Pure C long sum_th(const struct with_th_t *all, size_t size) { long result = 0; size_t i; for (i = 0; i < size; ++i) { result += all[i].th; } return result; }
  • 15. Модуль на C while ((item = PyIter_Next(iterator)) != NULL) { PyObject *field = PyObject_GetAttr( item, interned_th); if (field == NULL) { Py_DECREF(result); Py_DECREF(item); return NULL; } PyObject *nw = PyNumber_Add( result, field); Py_DECREF(result); ...
  • 16. Python def sum_th(lst): result = 0 for i in lst: #! result += i.th #!!!111 return result
  • 18. Итого Python Pure C C module строк 5 7 28 • На реальном коде разница будет меньше! • Но разница будет.
  • 19. ??? Долго писать: • много кода; • сложность отладки. Потеря скорости: • boxing/unboxing.
  • 20. boxing/unboxing PyInt_FromSize_t PyInt_FromLong PyLong_FromSize_t fill_free_list _PyLong_FromByteArray _PyLong_New
  • 21. boxing/unboxing PyInt_AsLong PyInt_Check tp_as_number PyInt_AS_LONG PyInt_Check PyInt_AS_LONG PyLong_Check PyLong_AsLong
  • 22. Cython • страшная смесь Python’а и C; • понимает подмножество Python; • генерирует C-код; • def/cdef/cpdef. • lxml, SciPy, ...
  • 23. читайте FAQ; • используйте cdef; • не *q = 0, а q[0] = 0; • не путайте float и double; • cdef для переменных, которые участвуют в циклах; • cython -a.
  • 24. shlex.split • Ускорим простую программу в XX раз. • За 15 минут. • Сейчас это займет куда меньше времени.
  • 25. Задача 127.0.0.1 "it’s query" "client id" 12.0 ... • str.split не сработает: некоторые поля окружены кавычками. • 25 миллионов строк в день. • 680 миллионов строк в месяц.
  • 26. Что имеем sm = 0.0 cnt = 0 for line in sys.stdin: split = shlex.split(line) try: sm += float(split[12]) cnt += 1 except ValueError: pass
  • 27. Что имеем Используем стандартный shlex.split и файл в 900 строк. SUMMARY real time: 0.870 [ 0.875 +-0.004] 0.878 sys time: 0.004 [ 0.007 +-0.002] 0.008 user time: 0.844 [ 0.860 +-0.014] 0.868 ≈ 1 мс на строку. ≈ 7 часов на дневной лог
  • 28. Что имеем Своя, очень простая реализация. Тот же файл. SUMMARY real time: 0.603 [ 0.614 +-0.009] 0.621 sys time: 0.000 [ 0.001 +-0.002] 0.004 user time: 0.596 [ 0.601 +-0.006] 0.608 ≈ 0.7 мс на строку. ≈ 5 часов на дневной лог
  • 29. Что имеем Та же реализация, но откомпилированная в cython. Тот же файл. SUMMARY real time: 0.650 [ 0.664 +-0.013] 0.675 sys time: 0.000 [ 0.000 +-0.000] 0.000 user time: 0.640 [ 0.655 +-0.014] 0.668
  • 33. Time table время 0.603 исходный код 0.532 объявить типы 0.151 cdef class 0.029 char * ≈ 14 минут на дневной лог файл.
  • 34. Cython vs ... • boost::python; • SWIG; • expy; • ...
  • 35. Проблема boxing/unboxing 1 Найдем функцию, что занимает >50% времени. 2 Перепишем её на C. 3 ???
  • 36. Проблема boxing/unboxing 1 Найдем функцию, что занимает >50% времени. 2 Перепишем её на C. 3 ??? 4 Нет профита.
  • 37. Профилирование Подход ускорения через профилирование порочен: • не надо думать, что остальная программа ускорится; • что делать, если нет очевидного медленного места?
  • 38. Кроме этого • на каждый вызов функции надо преобразовывать данные; • в вырожденных случаях, это будет дольше самой функции; • мы вынуждены переписывать все места, где мы вызываем нашу функцию.
  • 39. Решение • частичная оптимизация; • cpdef; • перетаскивание функционала в cython, а потом в C; • это не панацея.
  • 40. Сложные данные Как работать с данными из C и Python. • proxy/wrapper; • копия.
  • 41. Копирование vs proxy proxy: • каждый раз преобразовывать; • но есть кеш объектов; • код на C работает быстро; • это тот код, который нас интересует.
  • 42. Копирование vs proxy Копирование: • идеально для неизменяемых объектов; • но требует много памяти; • fork...
  • 44. GIL это не проблема
  • 45. GIL • он нужен, пока мы работаем с python данными; • в критичных местах, мы не работаем с python данными; • мы можем его отпустить.
  • 46. proxy: запрет создания из python cdef class _Q: def __cinit__(self, ....): .... def __init__(self, ....): raise TypeError, "" cpdef _Q Q(....): cdef _Q q = _Q.__new__(_Q) return q
  • 47. Кеширование объектов • попробуйте id; • попробуйте перенумеровать в зависимости от частоты; • убедитесь, что у вас неизменяемые типы; • треды...
  • 48. Кеширование прокси объектов Python container a[0] a[1] ... a[n] C struct ... void *extra container struct Python proxy
  • 49. Кеширование прокси объектов Python container a[0] a[1] ... a[n] C struct ... void *extra __getitem__ Python proxy container struct next Python proxy ...
  • 50. Кеширование прокси объектов cdef _Point point_wrap(point_t *x): cdef _Point result if x.extra != NULL: return <_Point>x.extra result = _Point.__new__(_Point) result.inner = x if is_common_point(x): print ’cache’ x.extra = <void *>result return result
  • 51. Мои выводы • python это удобно; • С это быстро; • cython объединяет; • все будет хорошо.
  • 52. Благодарю за внимание shigin@rambler-co.ru friendfeed.com/shigin