Jakie narzędzia lub metody są dostępne, aby przyspieszyć kod napisany w Pythonie?

29

Tło: Myślę, że mógłbym chcieć przenieść część kodu, który oblicza macierzowe produkty wykładnicze-wektorowe za pomocą metody podprzestrzeni Kryłowa od MATLAB-a do Pythona. (W szczególności funkcja expmvp Jitse Niesen , która wykorzystuje algorytm opisany w tym artykule ). Wiem jednak, że chyba, że ​​intensywnie korzystam z funkcji modułów pochodzących ze skompilowanych bibliotek (tj. Używam tylko surowego Pythona i nie wiele wbudowanych w funkcjach), to może być dość powolne.

Pytanie: Jakie narzędzia lub metody są dostępne, aby pomóc mi przyspieszyć kod napisany w Pythonie w celu zwiększenia wydajności? W szczególności interesują mnie narzędzia, które w jak największym stopniu automatyzują proces, choć mile widziane są również podejścia ogólne.

Uwaga: Mam starszą wersję algorytmu Jitse i od jakiegoś czasu go nie używałem. Stworzenie tego kodu może być bardzo łatwe, ale czułem, że byłby to dobry konkretny przykład i jest on związany z moimi własnymi badaniami. Omówienie mojego podejścia do implementacji tego konkretnego algorytmu w Pythonie to zupełnie inne pytanie.

Geoff Oxberry
źródło
Udzieliłem osobliwie pytającej odpowiedzi na to pytanie: scicomp.stackexchange.com/questions/2429/ ... Myślę, że podpowiedzi i linki będą dla ciebie pomocne.
AlexE
(h / t do @AlexE za uświadomienie mi tego) Zdecydowanie pokrywa się to pytanie, (jak) pisać symulacje, które działają szybciej? , i jakie są dobre strategie poprawy seryjnej wydajności mojego kodu? . Pewne scalenie może być w porządku. Napisałem o tym na Meta.
Geoff Oxberry
1
Oprócz dobrych odpowiedzi tutaj, spójrz na ten link .
Mike Dunlavey,

Odpowiedzi:

40

Podzielę moją odpowiedź na trzy części. Profilowanie, przyspieszenie kodu Pythona za pomocą c i przyspieszenie Pythona za pomocą Pythona. Moim zdaniem Python ma jedne z najlepszych narzędzi do sprawdzania wydajności twojego kodu, a następnie drążenia w dół do rzeczywistych szyjek butelek. Przyspieszenie kodu bez profilowania jest jak próba zabicia jelenia za pomocą uzi.

Jeśli naprawdę interesują Cię tylko produkty mat-vec, polecam scipy.sparse .

Narzędzia Python do profilowania

profile i moduły cProfile : te moduły zapewniają standardową analizę czasu działania i stos wywołań funkcji. Ładnie jest zapisać ich statystyki, a korzystając z modułu pstats możesz przeglądać dane na wiele sposobów.

kernprof : to narzędzie łączy wiele procedur służących do wykonywania takich czynności jak synchronizacja kodu linia po linii

memory_profiler : to narzędzie generuje odcisk linii wiersz po wierszu kodu.

Timery IPython :timeitFunkcja jest całkiem przyjemna, gdy widzi różnice w funkcjach w szybki interaktywny sposób.

Przyspieszenie Pythona

Cython : cython to najszybszy sposób na skorzystanie z kilku funkcji w Pythonie i uzyskanie szybszego kodu. Możesz ozdobić funkcję wariantem cytonu Pythona, który generuje kod c. Jest to bardzo łatwe w utrzymaniu i może również łatwo łączyć się z innym ręcznie napisanym kodem w c / c ++ / fortran. Obecnie jest to zdecydowanie preferowane narzędzie.

ctypes : ctypes pozwoli ci napisać twoje funkcje wc, a następnie szybko je zawinąć dzięki prostej dekoracji kodu. Radzi sobie z bólem związanym z rzucaniem z PyObjectów i zarządzaniem gilem, aby wywołać funkcję c.

Istnieją inne podejścia do pisania kodu w C, ale wszystkie są nieco bardziej przydatne do pobierania biblioteki C / C ++ i pakowania w Pythona.

Podejścia oparte wyłącznie na języku Python

Jeśli chcesz pozostać w Pythonie głównie, radzę dowiedzieć się, jakich danych używasz i wybrać odpowiednie typy danych do implementacji algorytmów. Z mojego doświadczenia wynika, że ​​optymalizacja struktur danych zwykle odbywa się znacznie dalej, niż w przypadku jakiegokolwiek hakowania na niskim poziomie. Na przykład:

numpy : tablica poboczna bardzo szybka dla krokowych operacji tablic

numexpr : optymalizator wyrażeń tablic numpy. Pozwala na wielowątkowe wyrażenia tablic numpy, a także pozbywa się licznych tymczasowych marek numpy ze względu na ograniczenia interpretera Pythona.

blist : implementacja b-drzewa listy, bardzo szybka do wstawiania, indeksowania i przenoszenia wewnętrznych węzłów listy

pandy : ramki danych (lub tabele) bardzo szybkie analizy na tablicach.

pytable : szybkie strukturyzowane tabele hierarchiczne (jak hdf5), szczególnie przydatne do obliczeń poza zapytaniami i zapytań do dużych danych.

aterrel
źródło
3
Możesz także używać ctypów do wywoływania procedur Fortrana.
Matthew Emmett
Mówiąc o pakowaniu kodu, a co z f2py?
astrojuanlu
f2py to świetne narzędzie, z którego korzysta wiele osób w społeczności. fwrap jest nowszym zamiennikiem, ponieważ f2py pokazuje swój wiek, ale tak naprawdę nie jest kompletny.
aterrel
Dzięki! Tego rodzaju zasobów szukałem. Byłem świadomy tylko niektórych z nich i tylko przelotnie (lub patrząc na nie w Internecie). Aron ciągle wspomina o numexpr. Jak to działa? Czy to by miało zastosowanie?
Geoff Oxberry
7

Przede wszystkim, jeśli dostępna jest implementacja C lub Fortran (funkcja MATLAB MEX?), Dlaczego nie piszesz otoki Pythona?

Jeśli chcesz mieć własną implementację nie tylko otoki, zdecydowanie zalecam użycie modułu numpy do algebry liniowej. Upewnij się, że jest on połączony ze zoptymalizowanym plikiem blas (takim jak ATLAS, GOTOblas, uBLAS, Intel MKL, ...). I użyj Cython lub splot. Przeczytaj ten artykuł dotyczący wydajności w Pythonie, aby uzyskać dobre wprowadzenie i test porównawczy. Różne implementacje w tym artykule są dostępne do pobrania tutaj dzięki uprzejmości Travisa Oliphanta (Numpy-guru).

Powodzenia.

GertVdE
źródło
Ten artykuł dotyczący wydajności w Pythonie wydaje się nieco przestarzały, nie wspomina o niektórych nowszych dostępnych narzędziach, takich jak numexpr.
Aron Ahmadia
Rzeczywiście przeoczyłem numexpr. Byłoby miło uruchomić ten sam test porównawczy laplace z numexpr ...
GertVdE
Jest scipy.weavenadal używany i rozwijany? Wygląda na to, że artykuł Performance Python pokazuje, że może być szybki w użyciu i daje całkiem niezłą poprawę prędkości, ale rzadko widuje się go poza tym artykułem.
Ken
@Ken: scipy.weave, o ile mi wiadomo, nie jest już aktywnie rozwijany. Został zachowany dla kompatybilności wstecznej, ale nowe projekty są zachęcane do korzystania z Cython.
GertVdE
Dla GotoBLAS i NumPy / SciPy, patrz der-schnorz.de/2012/06/optimized-linear-algebra-and-numpyscipy
AlexE
4

Zasadniczo zgadzam się z innymi odpowiedziami. Najlepsze opcje szybkiego pythonkodu numerycznego to

  • Używaj specjalistycznych bibliotek takich jak numpy
  • zawiń swój istniejący kod, aby python-program mógł go wywołać bezpośrednio

Ale jeśli chcesz zaprogramować cały algorytm od zera (cytuję: „Używam tylko surowego Pythona”), możesz rozważyć http://pypy.org/ implementację JIT (Just In Time) python. Nie byłem w stanie użyć go do mojego projektu (ponieważ to zależy od tego, numpya pypychłopaki pracują nad tym, aby to wspierać), ale testy porównawcze są imponujące ( http://speed.pypy.org/ )

bgschaid
źródło