Konwertować program w Pythonie na kod C / C ++? [Zamknięte]


149

czy można przekonwertować program w języku Python na C / C ++?

Muszę zaimplementować kilka algorytmów i nie jestem pewien, czy luka w wydajności jest wystarczająco duża, aby uzasadnić cały ból, przez który przechodziłbym, robiąc to w C / C ++ (w czym nie jestem dobry). Myślałem o napisaniu jednego prostego algorytmu i porównaniu go z tak przekonwertowanym rozwiązaniem. Jeśli samo to jest znacznie szybsze niż wersja Pythona, nie mam innego wyjścia, jak zrobić to w C / C ++.


32
Chociaż Python traci na testach porównawczych, pamiętaj, że spowolnienie 50x lub 100x jest nadal negatywne, jeśli obliczenia kończą się w Pythonie w ciągu kilku sekund, a nawet nie jest prawdziwe, gdy wykonujesz dużo operacji we / wy lub masz okropny algorytm. Zamiast pytać „o ile wolniejszy jest Python?” powinieneś zapytać "czy Python jest wystarczająco szybki?" (i najprawdopodobniej tak jest, szczerze) - to także szybsze niż benchmarking lub pytanie tutaj.

1
Implementacja algorytmu w Pythonie jest dość szybka i prosta ... po prostu musisz to zrobić, a następnie sprawdzić, czy jest wystarczająco szybki. W większości przypadków można zoptymalizować algorytm, aby działał znacznie szybciej przy użyciu różnych struktur danych (dykt / zestawy zamiast list ...) lub różnych operacji. W każdym razie optymalizacja powinna nastąpić po zaimplementowaniu pierwszego szkicu algorytmu i przeprowadzeniu testów porównawczych / profilowaniu.
Bakuriu,

@delnan: w moim przypadku chodzi o czas obliczeń. Jeśli wariant C potrzebuje x godzin mniej, zainwestowałbym ten czas w pozwolenie algorytmom na dłuższe / ponowne działanie. Po prostu chcę się dowiedzieć (z grubsza), o ile wolniejszy byłby Python - gdyby to tylko kilka godzin, na pewno nie użyłbym języka, z którym nie czuję się komfortowo (możesz zepsuć najlepsze rozwiązania problemów ze złymi implementacjami: P).
CrazyFlyingCloseline,

@ delnan ma rację co do tego, że Python prawdopodobnie jest wystarczająco szybki do wielu rzeczy. Nawet jeśli jest wolniejszy, łatwość rozwoju, konserwacji i przyszłych ulepszeń są ważnymi czynnikami do rozważenia.
martineau

„x godzin”? Jak duże to jest? Czy wykonałeś test porównawczy implementacji? Czy masz pomiary? Czy sprofilowałeś wdrożenie? A może próbujesz przedwcześnie zoptymalizować rozwiązanie?
S.Lott,

Odpowiedzi:


115

Tak. Spójrz na Cythona . Robi tylko to: konwertuje Pythona do C w celu przyspieszenia.


6
Oczywiście nic cię to nie uratuje, chyba że dodasz kilka cdefdeklaracji i tym samym wprowadzisz statyczne pisanie (w przeciwnym razie po prostu żonglujesz nieprzezroczystymi PyObject *rzeczami). I nigdy nie będzie tak szybki jak zwykły C, ponieważ zwykle łączy się z Pythonem (100% lub więcej? Tylko dla zwykłego kodu numerycznego, który w ogóle nie współpracuje z Pythonem przez większość czasu!). Ale poza tym, tak, może to przynieść całkiem sprytne przyspieszenie.

7
@delnan: Właściwie to coś ci oszczędza. Większość czystego kodu Pythona będzie działać szybciej po kompilacji. Ale tak, dzięki cdefs i statycznemu typowaniu naprawdę zaczynasz dostrzegać różnice. I interfejs z Pythonem, który otrzymujesz we wszystkich przypadkach, w których używasz C z Pythona.
Lennart Regebro

136

Jeśli wariant C potrzebuje x godzin mniej, zainwestowałbym ten czas w pozwolenie algorytmom na dłuższe / ponowne działanie

„inwestować” nie jest tutaj właściwym słowem.

  1. Zbuduj działającą implementację w Pythonie. Skończysz to na długo przed ukończeniem wersji C.

  2. Zmierz wydajność za pomocą profilera języka Python. Rozwiąż wszystkie znalezione problemy. Zmień struktury danych i algorytmy, jeśli to konieczne, aby naprawdę zrobić to poprawnie. Skończysz to na długo przed ukończeniem pierwszej wersji w C.

  3. Jeśli nadal jest zbyt wolny, przetłumacz ręcznie dobrze zaprojektowany i starannie skonstruowany Python na C.

    Ze względu na sposób, w jaki działa to z perspektywy czasu, wykonanie drugiej wersji z istniejącego Pythona (z istniejącymi testami jednostkowymi i istniejącymi danymi profilowania) będzie nadal szybsze niż próba wykonania kodu C od zera.

Ten cytat jest ważny.

Zasada Thompsona dla początkujących konstruktorów teleskopów
Szybciej jest zrobić czterocalowe lustro, a następnie sześciocalowe lustro, niż sześciocalowe lustro.


Instytut Billa McKeenana Wanga


15
Pomimo ogromnej liczby punktów, nie wiem, jak to odpowiada na pytanie.
Audrius Meskauskas

29

Shed Skin jest „(ograniczonym) kompilatorem Pythona do C ++”.


3
+1 Jedną z zalet Shed Skin jest wnioskowanie o typie : jeśli możliwe jest zgadywanie typów zmiennych z przebiegu programu, unika się dynamicznego sprawdzania typu. Zwykle prowadzi to do skrócenia kodu C ++, który można odczytać i skompilować do szybszych programów.
Kyss Tao

1
Istnieje również transpiler Python → 11l → C ++ , który jest również ograniczonym kompilatorem Pythona do C ++, ale obsługuje niektóre funkcje Pythona, które nie są obsługiwane przez Shed Skin (np. Funkcje zagnieżdżone / zamknięcia).
tav

17

Właśnie natknąłem się na to nowe narzędzie w wiadomościach dla hakerów.

Z ich strony - „Nuitka jest dobrym zamiennikiem dla interpretera Pythona i kompiluje każdą konstrukcję oferowaną przez CPython 2.6, 2.7, 3.2 i 3.3. Przekłada Pythona na program C ++, który następnie używa„ libpython ”do wykonania w taki sam sposób jak CPython robi to w bardzo zgodny sposób ”.


Ten projekt jest o wiele bardziej dojrzały niż inne podobne opcje. To zabawne, że tworzy plik binarny z .exerozszerzeniem na OSX, mimo że jest to całkowicie normalny plik wykonywalny Mach-O OSX. Wygląda na to, może być dobrym zamiennikiem pyinstaller, py2exe, py2app, itd. Te --recurse-***flagi są ważne, aby prawidłowo ustawić chociaż.
ccpizza

Nuitka jest świetna, ale utworzony kod C / C ++ wykorzystuje PyObject, który jest powiązany z implementacją kodu CPython-C. Nie wytwarza idiomatycznego kodu C.
Make42

8

Inną opcją - konwersję do C ++ oprócz Shed Skin - jest Pythran .

Cytując High Performance Python autorstwa Micha Gorelick i Iana Ozsvalda :

Pythran to kompilator Python-to-C ++ dla podzbioru Pythona, który obejmuje częściową numpyobsługę. Działa trochę jak Numba i Cython - dodajesz adnotacje do argumentów funkcji, a następnie przejmuje kontrolę z dalszą adnotacją typu i specjalizacją kodu. Wykorzystuje możliwości wektoryzacji i możliwości zrównoleglania w oparciu o OpenMP. Działa tylko przy użyciu Pythona 2.7.

Jedną z bardzo interesujących cech Pythrana jest to, że będzie próbował automatycznie wykryć możliwości zrównoleglenia (np. Jeśli używasz a map) i przekształcić to w kod równoległy bez konieczności dodatkowego wysiłku z Twojej strony. Możesz również określić sekcje równoległe za pomocą pragma omp dyrektyw>; pod tym względem wygląda bardzo podobnie do obsługi OpenMP firmy Cython.

W tle Pythran weźmie zarówno normalny kod Pythona, jak i kod numpy i spróbuje agresywnie skompilować je do bardzo szybkiego C ++ - nawet szybciej niż wyniki Cythona.

Należy zauważyć, że ten projekt jest młody i możesz napotkać błędy; należy również pamiętać, że zespół programistów jest bardzo przyjazny i ma tendencję do naprawiania błędów w ciągu kilku godzin.


6

Wiem, że to starszy wątek, ale chciałem przekazać informacje, które uważam za pomocne.

Osobiście używam PyPy, które jest naprawdę łatwe do zainstalowania za pomocą pip. Używam zamiennie interpretera Python / PyPy, nie musisz w ogóle zmieniać swojego kodu i stwierdziłem, że jest około 40x szybszy niż standardowy interpreter Pythona (albo Python 2x lub 3x). Używam pyCharm Community Edition do zarządzania moim kodem i uwielbiam to.

Lubię pisać kod w Pythonie, ponieważ myślę, że pozwala skupić się bardziej na zadaniu niż na języku, co jest dla mnie ogromnym plusem. A jeśli chcesz, aby był jeszcze szybszy, zawsze możesz skompilować do pliku binarnego dla systemu Windows, Linux lub Mac (nie jest to proste, ale możliwe przy użyciu innych narzędzi). Z mojego doświadczenia wynika, że ​​podczas kompilacji uzyskuję około 3,5-krotne przyspieszenie w porównaniu z PyPy, czyli 140 razy szybciej niż w Pythonie. PyPy jest dostępny dla kodu Python 3x i 2x i ponownie, jeśli używasz IDE, takiego jak PyCharm, możesz bardzo łatwo przełączać się między, powiedzmy, PyPy, Cython i Python (chociaż wymaga trochę początkowej nauki i konfiguracji).

Niektórzy ludzie mogą się ze mną spierać w tej sprawie, ale uważam, że PyPy jest szybszy niż Cython. Ale oba są świetnym wyborem.

Edycja: Chciałbym zrobić kolejną krótką notatkę o kompilacji: kiedy kompilujesz, wynikowy plik binarny jest znacznie większy niż twój skrypt Pythona, ponieważ buduje w nim wszystkie zależności itp. Ale wtedy masz kilka wyraźnych korzyści: szybkość !, teraz aplikacja będzie działać na każdym komputerze (w zależności od tego, dla którego systemu operacyjnego skompilowałeś, jeśli nie na wszystkich. lol) bez Pythona lub bibliotek, zaciemnia również twój kod i jest technicznie gotowa do produkcji (do pewnego stopnia). Niektóre kompilatory generują również kod C, którego tak naprawdę nie oglądałem ani nie widziałem, czy jest przydatny lub po prostu bełkot. Powodzenia.

Mam nadzieję, że to pomoże.


2
Wiem, że to starszy komentarz, ale dzięki!
kfrncs

Nie ma problemu, cieszę się, że to było przydatne.
jacktrader

Jakiego oprogramowania używasz do kompilacji z interpretacji PyPy?
Vasyl Vaskivskyi

Nie konkretnie PyPy, tylko skrypty .py. Nuitka, jeśli chcesz mieć „pliki wykonywalne C / C ++ lub kod źródłowy C / C ++” i PyInstaller, jeśli chcesz po prostu plik wykonywalny (łatwiejszy). Jest też py2exe, ale odniosłem z nim mniejszy sukces, chociaż jestem pewien, że sytuacja się poprawiła. PyInstaller jest również wieloplatformowy, nie tylko dla plików wykonywalnych Windows (działa z Linuksem i Macami). Nuitka jest wyjątkowa, ponieważ uważam, że jest to jedyny „kompilator”, który zwraca użyteczny kod źródłowy, który teoretycznie można by dalej optymalizować. Jest kilka innych, takich jak bbFreeze, cx_Freeze i py2app, ale nie próbowałem ich. Powodzenia!
jacktrader

1
Odkryłem również, że PyPy działa szybciej niż Cython. W jednym teście stwierdziłem, że PyPy ma taką samą szybkość jak wersja programu w C ++ (sortowanie przez wstawianie).
Nv7

5

Zdaję sobie sprawę, że brakuje odpowiedzi na całkiem nowe rozwiązanie. Jeśli w kodzie użyto Numpy, radziłbym wypróbować Pythran:

http://pythran.readthedocs.io/

W przypadku funkcji, które wypróbowałem, Pythran daje bardzo dobre wyniki. Wynikowe funkcje są równie szybkie, jak napisany kod Fortran (lub tylko nieco wolniejszy) i trochę szybciej niż (dość zoptymalizowane) rozwiązanie Cython.

Zaletą w porównaniu do Cythona jest to, że wystarczy użyć Pythrana na funkcji Pythona zoptymalizowanej pod kątem Numpy, co oznacza, że ​​nie trzeba rozszerzać pętli i dodawać typów dla wszystkich zmiennych w pętli. Pythran nie spieszy się z analizą kodu, aby rozumiał operacje na numpy.ndarray.

To także ogromna zaleta w porównaniu z Numbą czy innymi projektami opartymi na kompilacji just-in-time, dla których (o ile wiem) trzeba poszerzać pętle, żeby były naprawdę wydajne. A potem kod z pętlami staje się bardzo, bardzo nieefektywny, używając tylko CPython i Numpy ...

Wada Pythrana: brak klas! Ale ponieważ trzeba skompilować tylko te funkcje, które naprawdę wymagają optymalizacji, nie jest to zbyt denerwujące.

Kolejna uwaga: Pythran dobrze (i bardzo łatwo) obsługuje równoległość OpenMP. Ale nie sądzę, że mpi4py jest obsługiwane ...


4

http://code.google.com/p/py2c/ wygląda na możliwość - wspominają również na swojej stronie: Cython, Shedskin i RPython i potwierdzają, że konwertują kod Pythona na czysty C / C ++, który jest znacznie szybszy niż C / C ++ podziurawiony wywołaniami API Pythona. Uwaga: nie próbowałem tego, ale zamierzam ...


1
Wygląda na to, że Py2C to wciąż niedokończony projekt. Nie był aktualizowany od kilku lat, więc może nie działać.
Anderson Green
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.