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.