Предпосылки: я думаю, что я мог бы хотеть портировать некоторый код, который вычисляет матричные экспоненциально-векторные произведения, используя метод подпространства Крылова от MATLAB до Python. (В частности, функция expmvp Jitse Niesen , которая использует алгоритм, описанный в этой статье .) Однако я знаю, что если я не буду интенсивно использовать функции из модулей, производных от скомпилированных библиотек (то есть я использую только сырой Python, а не много встроенных в функции), то это может быть довольно медленно.
Вопрос: Какие инструменты или подходы доступны, чтобы помочь мне ускорить код, который я пишу на Python для производительности? В частности, мне интересны инструменты, которые максимально автоматизируют процесс, хотя общие подходы также приветствуются.
Примечание: у меня есть более старая версия алгоритма Jitse, и я не использовал его в течение некоторого времени. Может быть очень легко сделать этот код быстрым, но я чувствовал, что он послужит хорошим конкретным примером, и это связано с моими собственными исследованиями. Обсуждение моего подхода к реализации этого конкретного алгоритма в Python - это совсем другой вопрос.
источник
Ответы:
Я собираюсь разбить свой ответ на три части. Профилирование, ускорение кода 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), особенно полезные для вычислений вне ядра и запросов к большим данным.
источник
Прежде всего, если есть доступная реализация на C или Fortran (функция MATLAB MEX?), Почему бы вам не написать оболочку Python?
Если вы хотите, чтобы ваша собственная реализация была не только оболочкой, я настоятельно рекомендовал бы использовать модуль numpy для линейной алгебры. Убедитесь, что он связан с оптимизированным Blas (например, ATLAS, GOTOblas, UBLAS, Intel MKL, ...). И использовать Cython или ткать. Прочитайте эту статью о производительности Python для хорошего ознакомления и оценки. Различные реализации в этой статье доступны для загрузки здесь благодаря Тревису Олифанту (Numpy-гуру).
Удачи.
источник
scipy.weave
еще используется и разработан? Кажется, что статья о Performance Python показывает, что он может быть быстрым в использовании и дает довольно хорошее улучшение скорости, но я редко видел, чтобы это упоминалось за пределами этой статьи.В основном я согласен с другими ответами. Лучшие варианты для быстрого числового
python
кода:numpy
python
-программа могла вызывать его напрямуюНо если вы хотите запрограммировать весь алгоритм с нуля (я цитирую: «Я использую только сырой Python»), то вы можете рассмотреть http://pypy.org/ реализацию JIT (Just In Time)
python
. Я не смог использовать его для своего проекта (потому что это зависит,numpy
иpypy
ребята постоянно работают над его поддержкой), но тесты довольно впечатляющие ( http://speed.pypy.org/ )источник
Некоторые из приведенных выше ссылок устарели, поэтому смотрите здесь:
http://wiki.scipy.org/PerformanceTips
http://wiki.scipy.org/PerformancePython
Некоторые идеи:
Numpy, Numba, Cython, Numexpr, Theano, Tensorflow, f2py, CPython C API, pypy, cffi, Pythran, Nuitka, swig, boost.python
источник