23
cpmoptimize Автоматическая оптимизация алгоритмов в Python Автор: Александр Борзунов, студент ИМКН УрФУ

Борзунов Александр, Cpmoptimize

Embed Size (px)

Citation preview

cpmoptimizeАвтоматическая оптимизация алгоритмов

в Python

Автор: Александр Борзунов, студент ИМКН УрФУ

Простой пример

Задача. Вычислить N-ое число Фибоначчи.

Простой пример

Тривиальный алгоритм:

N = 10 млн

25 минут 31 секундаУскоренный алгоритм:

18 секунд(в 85 раз быстрее)

Теория

Рассмотрим такой язык программирования:• Имеется несколько числовых переменных• С ними можно производить операции:

x = yx = 5

x += yx += 6x -= yx -= 7

x *= 8

• Используется интересный метод, описанный Александром Скидановым в 2012 году

Теория• Для выполнения программ на этом языке можно хранить вектор переменных, дополненный единицей:

• Описанные операции можно выполнять, домножая вектор на некоторую матрицу.

Теория• Присваивание другой переменной (x = y):

• Присваивание константы (x = 5):

Теория• Прибавление другой переменной (x += y):

• Домножение на константу (x *= 8):

Теория• Исполнение нескольких операций друг за другом:

• Самое интересное – циклы:

• Если использовать бинарное возведение в степень, то можно выполнять циклы значительно быстрее (не за O(n), а за O(log n) *)

* — при условии, что каждая итерация цикла работает за одинаковое время

Теория

Переходим к реализации• Практически применимой реализации

описанного метода с матрицами не существовало.

• Я решил реализовать этот метод для языка Python.

Поставленные задачи:• Простота в использовании• Требуется, чтобы декоратор ни при каких

условиях не мог «сломать» программу

Идея

• Сейчас компиляторы умеют заменять операции на более эффективные, предсказывать значения выражений, удалять или менять местами части кода.

• Задача создания эффективного кода частично переносится на компиляторы и интерпретаторы.

• Но компиляторы ещё не заменяют сам алгоритм вычислений на асимптотически более эффективный.

x * 4 x << 2

Пример: длинные циклыЗадача. Вычислить N-ый член последовательности, соответствующей правилу:

• Интуитивно понятно, как появляется очередной член последовательности, однако требуется время, чтобы придумать соответствующую математическую формулу.

Пример: длинные циклы• При использовании декоратора компьютер сам придумает, как быстро считать ответ на нашу задачу:

При N = 101000:

445 мс

Пример: линейно-рекуррентные соотношения

• Тогда придётся либо потратить усилия на составление и реализацию быстрого алгоритма, либо написать тривиальное решение и воспользоваться декоратором.• В обоих случаях производительность программ получится почти одинаковой.

• Помимо чисел Фибоначчи, иногда требуется быстро вычислять значения более сложных рекуррентных формул:

Почему именно Python?

+ Байт-код можно анализировать и изменять без вмешательства в интерпретатор

+ Преимущества метода с матрицами особенно проявляются при наличии длинной арифметики

‒ Проверки типов, выполняемые из-за динамической типизации

‒ Компиляторы C++ могли бы создавать ещё более быстрые программы

Описание библиотеки

cpmoptimize - compute the power of a matrix and optimize

cpmoptimize.xrange(…)• Замена стандартному xrange, поддерживающая long

cpmoptimize.cpmoptimize(strict=False, iters_limit=5000, …)• Можно указать, в каких случаях стоит применять

оптимизацию, и что делать, когда применить её не удалось

Алгоритм работы декоратора

I. Этап применения декоратора:1. Найти следующий цикл for2. Проверить, что тело цикла состоит только из

допустимых операций3. Преобразовать тело цикла в список

элементарных операций с ограниченным кругом переменных

4. Установить перед циклом «ловушку»

Выражения и вынос кода за цикл

• Декоратор определит, что значения k и m в выражении (k ** m) & 676 не зависят от того, на какой итерации цикла они используются, а значит значение всего выражения можно вычислить один раз перед циклом.

• Код справа уже можно оптимизировать с помощью матриц.

Алгоритм работы декоратораII. Этап срабатывания «ловушки»:

1. Проверим, что объект, по которому проходится цикл, и используемые переменные имеют нужные типы (это можно сделать только в run-time)

2. Если проверка не удалась, то оптимизацию применить нельзя и нужно запустить исходный байт-код цикла

3. Иначе построим необходимые матрицы4. Возведём их в степень5. Присвоим переменным конечные

значения

Что ещё можно реализовать?• Замена операций (требуется сохранение

ассоциативности умножения матриц или подобного свойства):

Пример:

• Поддержка вложенных циклов• Обработка предсказуемых условий

Установка и документация• Установить библиотеку можно одной командой:

$ sudo pip install cpmoptimize• Если прописать её в зависимостях у своего проекта,

при установке через pip она докачается автоматически.

Хабрахабрhttp://habrahabr.ru/post/236689/

GitHubhttps://github.com/borzunov/cpmoptimize

Python Package Indexhttps://pypi.python.org/pypi/cpmoptimize

Вопросы?

Спасибо за внимание!