Convertire il programma Python in codice C / C ++? [chiuso]


149

è possibile convertire un programma Python in C / C ++?

Ho bisogno di implementare un paio di algoritmi e non sono sicuro che il divario di prestazioni sia abbastanza grande da giustificare tutto il dolore che subirei quando lo faccio in C / C ++ (di cui non sono bravo). Ho pensato di scrivere un semplice algoritmo e confrontarlo con una soluzione così convertita. Se quello da solo è significativamente più veloce della versione di Python, allora non avrò altra scelta che farlo in C / C ++.


32
Per quanto Python perda sui benchmark, tieni presente che quel rallentamento 50x o 100x è ancora trascurabile se il calcolo termina in pochi secondi in Python, e nemmeno vero quando esegui molti I / O o hai un orribile algoritmo. Piuttosto che chiedere "quanto è più lento Python?" dovresti chiedere "Python è abbastanza veloce?" (ed è molto probabilmente, onestamente), è anche più veloce del benchmarking o della domanda qui.

1
L'implementazione di un algoritmo in Python è abbastanza veloce e semplice ... devi semplicemente farlo e poi verificare se è abbastanza veloce. La maggior parte delle volte è possibile ottimizzare l'algoritmo per l'esecuzione molto più veloce utilizzando diverse strutture di dati (dict / sets invece di elenchi ...) o diverse operazioni. L'ottimizzazione dovrebbe comunque avvenire dopo aver già implementato una prima bozza dell'algoritmo e averlo confrontato / profilato.
Bakuriu,

@delnan: nel mio caso si tratta solo di tempo di calcolo. Se la variante C ha bisogno di x ore in meno, allora investirei quel tempo nel lasciare che gli algoritmi funzionino più a lungo / di nuovo. Voglio semplicemente scoprire (approssimativamente) quanto sarebbe più lento Python - se fosse solo un paio d'ore certamente non userei un linguaggio con cui non sono a mio agio (puoi rovinare le migliori soluzioni ai problemi con cattive implementazioni: P).
CrazyFlyingCloseline

@ delnan ha ragione sul fatto che Python probabilmente è abbastanza veloce per molte cose. Anche quando rallenta, la facilità di sviluppo, manutenzione e miglioramento futuro sono fattori importanti da considerare.
martineau,

"x ore"? Quanto è grande? Hai confrontato un'implementazione? Avete misure? Hai profilato l'implementazione? O stai cercando di ottimizzare prematuramente la soluzione?
S.Lott

Risposte:


115

Sì. Guarda Cython . Fa proprio questo: converte Python in C per accelerazioni.


6
Ovviamente ciò non ti salverà nulla a meno che tu non aggiunga un mucchio di cdefdichiarazioni e quindi introduca la tipizzazione statica (altrimenti manipoli solo PyObject *cose opache ). E non diventerà mai così veloce come la semplice C perché di solito si interfaccia con Python (100% o più? Solo per un semplice codice numerico che non si interfaccia affatto con Python per la maggior parte del tempo!). Ma a parte questo, sì, può darti una velocità piuttosto deviante.

7
@delnan: In effetti, ti fa risparmiare qualcosa. Il codice Python più puro sarà più veloce dopo la compilazione. Ma sì, con i cdefs e la digitazione statica inizi davvero a vedere differenze. E l'interfaccia con Python si ottiene in tutti i casi in cui si utilizza C da Python.
Lennart Regebro,

136

Se la variante C necessita di x ore in meno, allora investerei quel tempo nel lasciare che gli algoritmi funzionino più a lungo / di nuovo

"investire" non è la parola giusta qui.

  1. Crea un'implementazione funzionante in Python. Finirai molto prima di finire una versione C.

  2. Misura le prestazioni con il profiler Python. Risolvi tutti i problemi che riscontri. Modificare le strutture dati e gli algoritmi, se necessario, per farlo davvero correttamente. Finirai molto prima di finire la prima versione in C.

  3. Se è ancora troppo lento, traduci manualmente il Python ben progettato e attentamente costruito in C.

    A causa del modo in cui funziona il senno di poi, eseguire la seconda versione da Python esistente (con test unitari esistenti e con dati di profilatura esistenti) sarà ancora più veloce rispetto al tentativo di eseguire il codice C da zero.

Questa citazione è importante.

La regola di Thompson per i produttori di telescopi per la prima volta
È più veloce realizzare uno specchio da quattro pollici e poi uno da sei pollici piuttosto che fare uno specchio da sei pollici.

Bill McKeenan
Wang Institute


15
Indipendentemente dall'enorme punteggio, non vedo come questo risponda alla domanda.
Audrius Meskauskas,

29

Shed Skin è "un compilatore (limitato) da Python a C ++".


3
+1 un vantaggio di Shed Skin è l' inferenza del tipo : se è possibile indovinare tipi variabili dal flusso del programma, si evita il controllo dinamico del tipo. Questo in genere porta a un codice C ++ più breve che è effettivamente possibile leggere e compilare per programmi più veloci.
Kyss Tao,

1
Esiste anche un transpiler Python → 11l → C ++ , che è anche un compilatore limitato da Python a C ++, ma supporta alcune funzionalità di Python, che non è supportato con Shed Skin (ad esempio funzioni / chiusure nidificate).
tav

17

Ho appena scoperto questo nuovo strumento nelle notizie sugli hacker.

Dalla loro pagina - "Nuitka è un buon sostituto dell'interprete Python e compila tutti i costrutti offerti da CPython 2.6, 2.7, 3.2 e 3.3. Traduce Python in un programma C ++ che quindi usa" libpython "per eseguire allo stesso modo di CPython lo fa, in modo molto compatibile. "


Questo progetto è molto più maturo di altre opzioni simili. È divertente che crea il binario con .exeun'estensione su OSX anche se è un eseguibile OSX Mach-O perfettamente normale. Sembra che potrebbe essere un buon sostituto per pyinstaller, py2exe, py2app, ecc Le --recurse-***bandiere sono importanti per impostare correttamente però.
ccpizza,

Nuitka è eccezionale, ma il codice C / C ++ creato utilizza PyObject che si lega all'implementazione del codice CPython-C. Non produce codice C idiomatico.
Make42

8

Un'altra opzione - per convertire in C ++ oltre a Shed Skin - è Pythran .

Per citare High Performance Python di Micha Gorelick e Ian Ozsvald :

Pythran è un compilatore da Python a C ++ per un sottoinsieme di Python che include il numpysupporto parziale . Funziona un po 'come Numba e Cython: annoti gli argomenti di una funzione e poi prende il posto con un'ulteriore annotazione del tipo e specializzazione del codice. Sfrutta le possibilità di vettorializzazione e le possibilità di parallelizzazione basate su OpenMP. Funziona solo con Python 2.7.

Una caratteristica molto interessante di Pythran è che tenterà di individuare automaticamente le opportunità di parallelizzazione (ad esempio, se si utilizza a map) e di trasformarlo in codice parallelo senza richiedere ulteriori sforzi da parte tua. Puoi anche specificare sezioni parallele usando pragma omp > direttive; a questo proposito, sembra molto simile al supporto OpenMP di Cython.

Dietro le quinte, Pythran prenderà sia il normale codice Python sia il codice intorpidito e tenterà di compilarli in modo aggressivo in C ++ molto veloce, anche più velocemente dei risultati di Cython.

Dovresti notare che questo progetto è giovane e potresti riscontrare dei bug; dovresti anche notare che il team di sviluppo è molto gentile e tende a correggere i bug nel giro di poche ore.


6

So che questo è un thread più vecchio, ma volevo dare ciò che ritengo essere un'informazione utile.

Personalmente uso PyPy che è davvero facile da installare usando pip. Uso in modo intercambiabile l'interprete Python / PyPy, non è necessario modificare il codice e l'ho trovato all'incirca 40 volte più veloce dell'interprete standard di Python (Python 2x o 3x). Uso pyCharm Community Edition per gestire il mio codice e lo adoro.

Mi piace scrivere codice in Python poiché penso che ti permetta di concentrarti più sull'attività che sulla lingua, il che è un grande vantaggio per me. E se ne hai bisogno per essere ancora più veloce, puoi sempre compilare un file binario per Windows, Linux o Mac (non semplice ma possibile con altri strumenti). Dalla mia esperienza, durante la compilazione ottengo circa 3,5 volte la velocità rispetto a PyPy, il che significa 140 volte più veloce di Python. PyPy è disponibile per codice Python 3x e 2x e di nuovo se si utilizza un IDE come PyCharm è possibile scambiare tra PyPy, Cython e Python molto facilmente (richiede un po 'di apprendimento iniziale e configurazione).

Alcune persone potrebbero discutere con me su questo, ma trovo che PyPy sia più veloce di Cython. Ma sono entrambe ottime scelte.

Modifica: Vorrei fare un'altra breve nota sulla compilazione: quando compili, il binario risultante è molto più grande del tuo script Python in quanto costruisce tutte le dipendenze in esso, ecc. Ma poi ottieni alcuni vantaggi distinti: velocità !, ora l'app funzionerà su qualsiasi macchina (a seconda del sistema operativo che hai compilato, se non tutti. lol) senza Python o librerie, offusca anche il tuo codice ed è tecnicamente pronta per la produzione (in una certa misura). Alcuni compilatori generano anche codice C, che non ho mai visto o visto se è utile o semplicemente incomprensibile. In bocca al lupo.

Spero che aiuti.


2
So che questo è un commento più vecchio, ma grazie!
kfrncs,

Nessun problema, sono contento che sia stato utile.
jacktrader,

Quale software usi per compilare dall'interpretazione di PyPy?
Vasyl Vaskivskyi,

Non specificamente PyPy, solo script .py. Nuitka se vuoi "eseguibile C / C ++ o codice sorgente C / C ++" e PyInstaller se vuoi solo un eseguibile (più semplice). C'è anche py2exe ma ho avuto meno successo con esso, anche se sono sicuro che le cose sono migliorate. PyInstaller è anche multipiattaforma, non solo per gli eseguibili di Windows (funziona con Linux e Mac). Nuitka è unico perché penso che sia l'unico "compilatore" che ti restituisce il codice sorgente utilizzabile che in teoria potresti ottimizzare ulteriormente. Ce ne sono alcuni altri come bbFreeze, cx_Freeze e py2app ma non li ho provati. Buona fortuna!
jacktrader,

1
Ho anche scoperto che PyPy corre più veloce di Cython. In un test ho effettivamente scoperto che PyPy aveva la stessa velocità di una versione C ++ del programma (insertion sort).
NV7,

5

Mi rendo conto che manca una risposta su una soluzione abbastanza nuova. Se Numpy è usato nel codice, consiglierei di provare Pythran:

http://pythran.readthedocs.io/

Per le funzioni che ho provato, Pythran dà risultati estremamente buoni. Le funzioni risultanti sono altrettanto veloci come il codice Fortran scritto (o solo leggermente più lento) e un po 'più veloce della soluzione Cython (abbastanza ottimizzata).

Il vantaggio rispetto a Cython è che devi solo usare Pythran sulla funzione Python ottimizzata per Numpy, il che significa che non devi espandere i loop e aggiungere tipi per tutte le variabili nel loop. Pythran impiega il suo tempo ad analizzare il codice in modo che comprenda le operazioni numpy.ndarray.

È anche un enorme vantaggio rispetto a Numba o ad altri progetti basati sulla compilazione just-in-time per i quali (per quanto ne sappia), è necessario espandere i loop per essere davvero efficienti. E poi il codice con i loop diventa molto inefficiente usando solo CPython e Numpy ...

Uno svantaggio di Pythran: nessuna lezione! Ma poiché devono essere compilate solo le funzioni che devono davvero essere ottimizzate, non è molto fastidioso.

Un altro punto: Pythran supporta bene (e molto facilmente) parallelismo OpenMP. Ma non credo che mpi4py sia supportato ...


4

http://code.google.com/p/py2c/ sembra una possibilità - citano anche sul loro sito: Cython, Shedskin e RPython e confermano che stanno convertendo il codice Python in puro C / C ++ che è molto più veloce di C / C ++ pieno di chiamate API Python. Nota: non l'ho provato ma ho intenzione di ..


1
Sembra che Py2C sia ancora un progetto incompiuto. Non è stato aggiornato da alcuni anni, quindi potrebbe essere defunto.
Anderson Green,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.