Antecedentes: Eu acho que posso querer portar algum código que calcule produtos vetoriais exponenciais da matriz usando um método de subespaço Krylov do MATLAB ao Python. (Especificamente, a função expmvp de Jitse Niesen , que usa um algoritmo descrito neste documento .) No entanto, eu sei que, a menos que eu faça uso pesado de funções de módulos derivados de bibliotecas compiladas (ou seja, eu só uso Python bruto e não muitos em funções), então pode ser bem lento.
Pergunta: Quais ferramentas ou abordagens estão disponíveis para me ajudar a acelerar o código que escrevo no Python para desempenho? Em particular, estou interessado em ferramentas que automatizem o processo o máximo possível, embora abordagens gerais também sejam bem-vindas.
Nota: Eu tenho uma versão mais antiga do algoritmo de Jitse e não a uso há algum tempo. Poderia ser muito fácil tornar esse código rápido, mas achei que seria um bom exemplo concreto e está relacionado à minha própria pesquisa. Debater minha abordagem para implementar esse algoritmo específico em Python é outra questão inteiramente.
fonte
Respostas:
Vou dividir minha resposta em três partes. Criação de perfil, acelerando o código python via ce acelerando o python via python. É minha opinião que o Python possui algumas das melhores ferramentas para analisar o desempenho do seu código, em seguida, detalhar os gargalos reais da garrafa. Acelerar o código sem criar perfis é como tentar matar um cervo com uma uzi.
Se você realmente estiver interessado apenas em produtos mat-vec, eu recomendaria o scipy.sparse .
Ferramentas Python para criação de perfil
módulos profile e cProfile : esses módulos fornecerão sua análise padrão do tempo de execução e pilha de chamadas de funções. É muito bom salvar suas estatísticas e, usando o módulo pstats, você pode ver os dados de várias maneiras.
kernprof : esta ferramenta reúne muitas rotinas para fazer coisas como sincronização de código linha a linha
memory_profiler : esta ferramenta produz pegada de memória de linha por linha do seu código.
Temporizadores IPython : A
timeit
função é bastante boa para ver as diferenças nas funções de uma maneira rápida e interativa.Acelerando o Python
Cython : o cython é a maneira mais rápida de executar algumas funções em python e obter código mais rápido. Você pode decorar a função com a variante cython do python e ela gera código c. Isso é muito fácil de manutenção e também pode ser vinculado a outro código escrito à mão em c / c ++ / fortran com bastante facilidade. É de longe a ferramenta preferida hoje.
ctypes : ctypes permitirá que você escreva suas funções em ce as envolva rapidamente com a simples decoração do código. Ele lida com toda a dor de transmitir do PyObjects e gerenciar o gil para chamar a função c.
Existem outras abordagens para escrever seu código em C, mas são um pouco mais para pegar uma biblioteca C / C ++ e envolvê-la em Python.
Abordagens somente em Python
Se você deseja ficar dentro do Python principalmente, meu conselho é descobrir quais dados você está usando e escolher os tipos de dados corretos para implementar seus algoritmos. De acordo com minha experiência, você geralmente vai muito além, otimizando suas estruturas de dados e, em seguida, qualquer hack c de baixo nível. Por exemplo:
numpy : um arranjo contingente muito rápido para operações estritas de arrays
numexpr : um otimizador de expressão de matriz numpy. Ele permite expressões de array numpy multithreading e também se livra das inúmeras temporárias que o numpy cria devido a restrições do interpretador Python.
blist : uma implementação em árvore b de uma lista, muito rápida para inserir, indexar e mover os nós internos de uma lista
pandas : quadros de dados (ou tabelas) análises muito rápidas nas matrizes.
pytables : tabelas hierárquicas estruturadas rapidamente (como hdf5), especialmente boas para cálculos fora do núcleo e consultas para grandes dados.
fonte
Primeiro de tudo, se houver uma implementação C ou Fortran disponível (função MATLAB MEX?), Por que você não escreve um wrapper Python?
Se você deseja que sua própria implementação não seja apenas um invólucro, sugiro fortemente o uso do módulo numpy para coisas de álgebra linear. Verifique se ele está vinculado a um blas otimizado (como ATLAS, GOTOblas, uBLAS, Intel MKL, ...). E use Cython ou tecer. Leia este artigo do Performance Python para obter uma boa introdução e referência. As diferentes implementações deste artigo estão disponíveis para download aqui, cortesia de Travis Oliphant (Numpy-guru).
Boa sorte.
fonte
scipy.weave
Ainda é usado e desenvolvido? Parece que o artigo Performance Python mostra que ele pode ser rápido de usar e oferece uma melhora muito boa na velocidade, mas raramente o vi mencionado fora desse artigo.Basicamente, eu concordo com as outras respostas. As melhores opções para
python
códigos numéricos rápidos sãonumpy
python
agrupe seu código existente para que seu programa possa chamá-lo diretamenteMas se você deseja programar todo o algoritmo do zero (cito: "Eu uso somente o Python bruto"), convém considerar http://pypy.org/ uma implementação JIT (Just In Time) de
python
. Não fui capaz de usá-lo no meu projeto (porque isso dependenumpy
e ospypy
caras estão trabalhando corretamente para apoiá-lo), mas os benchmarks são impressionantes ( http://speed.pypy.org/ )fonte
Alguns dos links acima estão desatualizados, portanto, veja aqui:
http://wiki.scipy.org/PerformanceTips
http://wiki.scipy.org/PerformancePython
Algumas ideias:
Numpy, Numba, Cython, Numexpr, Theano, Tensorflow, f2py, API CPython C, pypy, cffi, Pythran, Nuitka, swig, boost.python
fonte