Upload
darya-zubova
View
523
Download
0
Embed Size (px)
Citation preview
cpmoptimizeАвтоматическая оптимизация алгоритмов
в Python
Автор: Александр Борзунов, студент ИМКН УрФУ
Простой пример
Тривиальный алгоритм:
N = 10 млн
25 минут 31 секундаУскоренный алгоритм:
18 секунд(в 85 раз быстрее)
Теория
Рассмотрим такой язык программирования:• Имеется несколько числовых переменных• С ними можно производить операции:
x = yx = 5
x += yx += 6x -= yx -= 7
x *= 8
• Используется интересный метод, описанный Александром Скидановым в 2012 году
Теория• Для выполнения программ на этом языке можно хранить вектор переменных, дополненный единицей:
• Описанные операции можно выполнять, домножая вектор на некоторую матрицу.
Теория• Исполнение нескольких операций друг за другом:
• Самое интересное – циклы:
• Если использовать бинарное возведение в степень, то можно выполнять циклы значительно быстрее (не за 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