Какие инструменты или подходы доступны для ускорения кода, написанного на Python?

29

Предпосылки: я думаю, что я мог бы хотеть портировать некоторый код, который вычисляет матричные экспоненциально-векторные произведения, используя метод подпространства Крылова от MATLAB до Python. (В частности, функция expmvp Jitse Niesen , которая использует алгоритм, описанный в этой статье .) Однако я знаю, что если я не буду интенсивно использовать функции из модулей, производных от скомпилированных библиотек (то есть я использую только сырой Python, а не много встроенных в функции), то это может быть довольно медленно.

Вопрос: Какие инструменты или подходы доступны, чтобы помочь мне ускорить код, который я пишу на Python для производительности? В частности, мне интересны инструменты, которые максимально автоматизируют процесс, хотя общие подходы также приветствуются.

Примечание: у меня есть более старая версия алгоритма Jitse, и я не использовал его в течение некоторого времени. Может быть очень легко сделать этот код быстрым, но я чувствовал, что он послужит хорошим конкретным примером, и это связано с моими собственными исследованиями. Обсуждение моего подхода к реализации этого конкретного алгоритма в Python - это совсем другой вопрос.

Джефф Оксберри
источник
Я дал Python-отдельный ответ на этот вопрос: scicomp.stackexchange.com/questions/2429/… Я думаю, что подсказки и ссылки там будут полезны для вас.
AlexE
(обращайтесь к @AlexE за информацией об этом) Этот вопрос определенно пересекается, (как) писать симуляции, которые работают быстрее? И Каковы некоторые хорошие стратегии для улучшения производительности последовательной моего кода? , Какое-то слияние может быть в порядке. Я написал об этом на Мете.
Джефф Оксберри
1
В дополнение к хорошим ответам здесь, посмотрите на эту ссылку .
Майк Данлавей

Ответы:

40

Я собираюсь разбить свой ответ на три части. Профилирование, ускорение кода Python с помощью C и ускорение Python с помощью Python. Я считаю, что в Python есть некоторые из лучших инструментов для анализа производительности вашего кода, а затем до реальных горловин. Ускорение кода без профилирования похоже на попытку убить оленя с помощью узи.

Если вы действительно заинтересованы только в продуктах mat-vec, я бы порекомендовал scipy.sparse .

Python инструменты для профилирования

модули profile и cProfile : эти модули предоставят вам стандартный анализ времени выполнения и стек вызовов функций. Довольно приятно сохранить их статистику, и с помощью модуля pstats вы можете просматривать данные различными способами.

kernprof : этот инструмент объединяет множество процедур для выполнения таких операций, как синхронизация кода за строкой

memory_profiler : этот инструмент производит построчную печать вашего кода.

Таймеры IPython :timeitфункция очень удобна для быстрого и быстрого просмотра различий в функциях.

Ускорение Python

Cython : Cython - это самый быстрый способ получить несколько функций в Python и получить более быстрый код. Вы можете украсить функцию с помощью варианта Python для Python, и он генерирует код c. Это очень удобно и может также легко ссылаться на другой рукописный код на c / c ++ / fortran. На сегодняшний день это наиболее предпочтительный инструмент.

ctypes : ctypes позволит вам написать свои функции в c, а затем быстро обернуть их простым украшением кода. Он обрабатывает все трудности приведения из PyObjects и управления gil для вызова функции c.

Существуют и другие подходы для написания вашего кода на C, но все они несколько больше для того, чтобы взять библиотеку C / C ++ и обернуть ее в Python.

Подходы только для Python

Если вы хотите в основном оставаться внутри Python, я советую выяснить, какие данные вы используете, и выбрать правильные типы данных для реализации ваших алгоритмов. По моему опыту, оптимизируя структуры данных, вы, как правило, получаете намного больше, чем любой хакер с низким уровнем. Например:

numpy : контингентный массив, очень быстрый для пошаговых операций с массивами

figurexpr : оптимизатор выражений с массивными массивами. Он допускает многопоточность выражений в массиве numpy, а также избавляет от многочисленных временных рядов, которые numpy создает из-за ограничений интерпретатора Python.

blist : реализация списка в виде b-дерева, очень быстрая для вставки, индексации и перемещения внутренних узлов списка

панды : фреймы данных (или таблицы) очень быстрая аналитика по массивам.

pytables : быстрые структурированные иерархические таблицы (например, hdf5), особенно полезные для вычислений вне ядра и запросов к большим данным.

aterrel
источник
3
Вы также можете использовать ctypes для вызова подпрограмм Fortran.
Мэтью Эммет
Говоря об упаковке кода, как насчет f2py?
astrojuanlu
f2py - отличный инструмент, который используется многими в сообществе. fwrap - более свежая замена, так как f2py показывает его возраст, но он еще не закончен.
aterrel
Благодарность! Это типы ресурсов, которые я искал. Я знал только о некоторых из них, и только мимоходом (или от просмотра их в Интернете). Арон продолжает упоминать Numberxpr. Как это работает? Будет ли это применяться?
Джефф Оксберри
7

Прежде всего, если есть доступная реализация на C или Fortran (функция MATLAB MEX?), Почему бы вам не написать оболочку Python?

Если вы хотите, чтобы ваша собственная реализация была не только оболочкой, я настоятельно рекомендовал бы использовать модуль numpy для линейной алгебры. Убедитесь, что он связан с оптимизированным Blas (например, ATLAS, GOTOblas, UBLAS, Intel MKL, ...). И использовать Cython или ткать. Прочитайте эту статью о производительности Python для хорошего ознакомления и оценки. Различные реализации в этой статье доступны для загрузки здесь благодаря Тревису Олифанту (Numpy-гуру).

Удачи.

GertVdE
источник
Эта статья, посвященная Performance Python, выглядит немного устаревшей, в ней не упоминаются некоторые новые инструменты, такие как Numberxpr.
Арон Ахмадиа
Я действительно пропустил Numberxpr. Было бы неплохо запустить тот же тест на лапласе с Numberxpr ...
GertVdE
Все scipy.weaveеще используется и разработан? Кажется, что статья о Performance Python показывает, что он может быть быстрым в использовании и дает довольно хорошее улучшение скорости, но я редко видел, чтобы это упоминалось за пределами этой статьи.
Кен
@Ken: scipy.weave, насколько я знаю, больше не находится в стадии активной разработки. Он сохраняется для обратной совместимости, но новым проектам рекомендуется использовать Cython.
GertVdE
Для GotoBLAS и NumPy / SciPy, смотрите der-schnorz.de/2012/06/optimized-linear-algebra-and-numpyscipy
AlexE
4

В основном я согласен с другими ответами. Лучшие варианты для быстрого числового pythonкода:

  • Используйте специализированные библиотеки, такие как numpy
  • оберните существующий код, чтобы ваша python-программа могла вызывать его напрямую

Но если вы хотите запрограммировать весь алгоритм с нуля (я цитирую: «Я использую только сырой Python»), то вы можете рассмотреть http://pypy.org/ реализацию JIT (Just In Time) python. Я не смог использовать его для своего проекта (потому что это зависит, numpyи pypyребята постоянно работают над его поддержкой), но тесты довольно впечатляющие ( http://speed.pypy.org/ )

bgschaid
источник