Perché compilare il codice Python?


241

Perché dovresti compilare uno script Python? Puoi eseguirli direttamente dal file .py e funziona bene, quindi c'è un vantaggio in termini di prestazioni o qualcosa del genere?

Ho anche notato che alcuni file nella mia applicazione vengono compilati in .pyc mentre altri no, perché?


Si può anche notare che, incluso l'avvio più rapido dell'applicazione, si ottiene anche sicurezza, se non è possibile condividere il codice se è un segreto aziendale.
Please_Dont_Bully_Me_SO_Lords,

@PSyLoCKe Davvero, davvero no. Il bytecode Python è davvero leggibile, perché il compilatore non ha bisogno di offuscarlo per ottimizzarlo. (Non che lo ottimizzi molto ...)
wizzwizz4

1
Il motivo per cui alcuni file vengono compilati automaticamente è perché vengono importati; ad esempio, se si utilizza import mylib.py, Python verrà compilato in mylib.pymodo da rendere le importistruzioni future un po 'più veloci. Se successivamente cambi mylib.py, verrà ricompilato la prossima volta che viene importato (Python utilizza la data del file per vedere che ciò accade.)
fyngyrz,

Risposte:


270

È compilato in bytecode che può essere usato molto, molto, molto più velocemente.

Il motivo per cui alcuni file non vengono compilati è che lo script principale, con il quale si invoca, python main.pyviene ricompilato ogni volta che si esegue lo script. Tutti gli script importati verranno compilati e archiviati sul disco.

Aggiunta importante di Ben Blank :

Vale la pena notare che durante l'esecuzione di uno script compilato ha un tempo di avvio più rapido (poiché non è necessario compilarlo), non viene eseguito più velocemente.


260
Vale la pena notare che durante l'esecuzione di uno script compilato ha un tempo di avvio più rapido (poiché non è necessario compilarlo), non viene eseguito più velocemente.
Ben Blank,

24
Un malinteso comune. Grazie per la condivisione.
matpie,

1
Oltre a non richiedere la compilazione, il file .pyc è quasi invariabilmente più piccolo. Soprattutto se commenti molto. Uno dei miei è 28419 come .py, ma solo 17879 come .pyc - quindi anche il tempo di caricamento è migliore. Infine, puoi precompilare gli script di livello superiore in questo modo: python -m compileall myscript.py
fyngyrz

1
C'è qualche differenza nel consumo di memoria? Sto testando Python su dispositivi embedded basati su mips cpu con solo 64 MB di RAM, quindi c'è qualche vantaggio nell'utilizzo della memoria quando si avvia una versione compilata di script Python?
valentt,

1
@valentt: probabilmente no. Non so molto degli interni di Python, ma non credo che l'analisi del bytecode richieda molta memoria in Python. Non riesco a pensare a qualcosa che ha bisogno di molta memoria per ricordare un certo stato.
Georg Schölly,

80

Il file .pyc è Python che è già stato compilato in codice byte. Python esegue automaticamente un file .pyc se ne trova uno con lo stesso nome di un file .py che invochi.

"An Introduction to Python" dice questo sui file Python compilati:

Un programma non funziona più velocemente quando viene letto da un file '.pyc' o '.pyo' rispetto a quando viene letto da un file '.py'; l'unica cosa che è più veloce sui file '.pyc' o '.pyo' è la velocità con cui vengono caricati.

Il vantaggio di eseguire un file .pyc è che Python non deve sostenere il sovraccarico di compilarlo prima di eseguirlo. Dato che Python si sarebbe compilato in byte-code prima di eseguire comunque un file .py, non ci dovrebbero essere miglioramenti delle prestazioni oltre a quello.

Quanto miglioramento puoi ottenere dall'utilizzo dei file .pyc compilati? Dipende da cosa fa lo script. Per uno script molto breve che stampa semplicemente "Hello World", la compilazione potrebbe costituire una grande percentuale del tempo totale di avvio e di esecuzione. Ma il costo della compilazione di uno script relativamente al tempo di esecuzione totale diminuisce per gli script con esecuzione più lunga.

Lo script che assegni nella riga di comando non viene mai salvato in un file .pyc. Solo i moduli caricati da quello script "principale" vengono salvati in quel modo.


3
In molti casi è difficile vedere una differenza, ma ho un particolare file Python con oltre 300.000 linee. (È un mucchio di calcoli matematici generati da un altro script per il test) Ci vogliono 37 secondi per la compilazione e solo 2 secondi per l'esecuzione.
Wojtow,

54

vantaggi:

Primo: offuscamento lieve e trattabile.

Secondo: se la compilazione risulta in un file significativamente più piccolo, otterrai tempi di caricamento più rapidi. Bello per il web.

Terzo: Python può saltare il passaggio della compilazione. Più veloce al carico iniziale. Bello per la CPU e il web.

Quarto: più commenterai, più piccolo sarà il file .pyco .pyorispetto al .pyfile sorgente .

Quinto: un utente finale con solo un file .pyco .pyoin mano ha molte meno probabilità di presentarti un bug causato da una modifica non ripristinata di cui ha dimenticato di parlarti.

Sesto: se stai mirando a un sistema incorporato, ottenere un file di dimensioni inferiori da incorporare può rappresentare un vantaggio significativo e l'architettura è stabile, quindi uno svantaggio, descritto di seguito, non entra in gioco.

Compilazione di alto livello

È utile sapere che è possibile compilare un file sorgente Python di livello superiore in un .pycfile in questo modo:

python -m py_compile myscript.py

Questo rimuove i commenti. Lascia docstringsintatto. Se anche tu vuoi sbarazzartene docstrings(potresti pensare seriamente al perché lo stai facendo), compila invece in questo modo ...

python -OO -m py_compile myscript.py

... e otterrai un .pyofile anziché un .pycfile; equamente distribuibile in termini di funzionalità essenziale del codice, ma più piccolo per le dimensioni dello stripped-out docstrings(e meno facilmente comprensibile per il successivo impiego se fosse decente docstringsin primo luogo). Ma vedi lo svantaggio tre, di seguito.

Nota che python usa la .pydata del file, se presente, per decidere se deve eseguire il .pyfile invece del file .pyco .pyo--- quindi modifica il tuo file .py, e .pyco .pyoè obsoleto e tutti i vantaggi che hai ottenuto sono persi. È necessario ricompilare al fine di ottenere il .pyco .pyobenefici di nuovo ancora una volta, ad esempio in quanto potrebbero essere.

svantaggi:

Primo: c'è un "cookie magico" .pyce .pyofile che indicano l'architettura di sistema in cui è stato compilato il file python. Se distribuisci uno di questi file in un ambiente di tipo diverso, si romperà. Se si distribuisce il .pyco .pyosenza il associato .pyda ricompilare o touchcosì sostituisce il .pyco .pyo, l'utente finale non può ripararlo neanche.

Secondo: se docstringssi salta l'uso -OOdell'opzione della riga di comando come descritto sopra, nessuno sarà in grado di ottenere tali informazioni, il che può rendere il codice più difficile (o impossibile).

Terzo: l' -OOopzione di Python implementa anche alcune ottimizzazioni secondo l' -Oopzione della riga di comando; ciò può comportare cambiamenti nel funzionamento. Le ottimizzazioni note sono:

  • sys.flags.optimize = 1
  • assert le dichiarazioni vengono saltate
  • __debug__ = Falso

Quarto: se hai intenzionalmente reso eseguibile il tuo script Python con qualcosa nell'ordine di #!/usr/bin/pythonsulla prima riga, questo viene eliminato .pyce .pyofile e tale funzionalità viene persa.

Quinto: in qualche modo ovvio, ma se compili il tuo codice, non solo può essere influenzato dal suo uso, ma il potenziale per gli altri di imparare dal tuo lavoro è ridotto, spesso in modo grave.


10

C'è un aumento delle prestazioni nell'esecuzione di Python compilato. Tuttavia, quando si esegue un file .py come modulo importato, python lo compilerà e lo memorizzerà, e finché il file .py non cambia, utilizzerà sempre la versione compilata.

Con qualsiasi linguaggio interpretato quando il file viene utilizzato, il processo è simile al seguente:
1. Il file viene elaborato dall'interpeter.
2. Il file viene compilato
3. Il codice compilato viene eseguito.

ovviamente usando il codice precompilato puoi eliminare il passaggio 2, questo vale per Python, PHP e altri.

Ecco un interessante post sul blog che spiega le differenze http://julipedia.blogspot.com/2004/07/compiled-vs-interpreted-languages.html
Ed ecco una voce che spiega il processo di compilazione di Python http://effbot.org/zone /python-compile.htm


9

Come già accennato, puoi ottenere un aumento delle prestazioni dalla compilazione del tuo codice Python in bytecode. Questo è generalmente gestito da Python stesso, solo per gli script importati.

Un altro motivo per cui potresti voler compilare il tuo codice Python, potrebbe essere quello di proteggere la tua proprietà intellettuale da essere copiata e / o modificata.

Puoi leggere di più al riguardo nella documentazione di Python .


2
Per quanto riguarda la protezione del codice, la compilazione non sarà di grande aiuto. La compilazione offusca - ma qualcuno con il desiderio otterrà il tuo codice indipendentemente.
Josh Smeaton,

1
@josh è sempre possibile, se si può accedere alla memoria o guardare le istruzioni per la cpu, con abbastanza tempo e saranno in grado di ricostruire la tua app.
UnkwnTech,

5
D'accordo, tuttavia, come ha affermato Unkwntech, ciò sarà sempre possibile, se la persona è abbastanza determinata. Ma sono convinto che basterà nella maggior parte delle situazioni, in cui in genere si desidera solo impedire alle persone di "correggere" il proprio codice ...
Simon B. Jensen,

Le lingue compilate in bytecode non sono in genere così difficili da invertire la compilazione a meno che non si facciano ulteriori passi per offuscarle - semplicemente compilare in generale non sarà sufficiente.
EJoshuaS - Ripristina Monica il

7

C'è sicuramente una differenza di prestazioni quando si esegue uno script compilato. Se si eseguono .pyscript normali , la macchina lo compila ogni volta che viene eseguito e ciò richiede tempo. Sulle macchine moderne questo è quasi impercettibile, ma man mano che la sceneggiatura cresce può diventare più un problema.


7

Qualcosa che non viene toccato è la compilazione da fonte a fonte . Ad esempio, nuitkatraduce il codice Python in C / C ++ e lo compila in codice binario che viene eseguito direttamente sulla CPU, anziché in bytecode Python che viene eseguito sulla macchina virtuale più lenta.

Questo può portare a significativi aumenti di velocità o ti consentirebbe di lavorare con Python mentre il tuo ambiente dipende dal codice C / C ++.


4

Usiamo il codice compilato per distribuire agli utenti che non hanno accesso al codice sorgente. Fondamentalmente per fermare programmatori inesperti che cambiano accidentalmente qualcosa o correggono bug senza dircelo.


2

Sì, le prestazioni sono la ragione principale e, per quanto ne so, l'unica ragione.

Se alcuni dei tuoi file non vengono compilati, forse Python non è in grado di scrivere nel file .pyc, forse a causa delle autorizzazioni della directory o qualcosa del genere. O forse i file non compilati non vengono mai caricati ... (gli script / i moduli vengono compilati solo al primo caricamento)


1

I principianti presumono che Python sia compilato a causa dei file .pyc. Il file .pyc è il bytecode compilato, che viene quindi interpretato. Quindi, se hai già eseguito il tuo codice Python e hai a portata di mano il file .pyc, verrà eseguito più velocemente la seconda volta, poiché non è necessario ricompilare il bytecode

compilatore: un compilatore è un pezzo di codice che traduce il linguaggio di alto livello in linguaggio macchina

Interpreti: gli interpreti convertono anche il linguaggio di alto livello in equivalenti binari leggibili automaticamente. Ogni volta che un interprete ottiene un codice di lingua di alto livello da eseguire, converte il codice in un codice intermedio prima di convertirlo nel codice macchina. Ogni parte del codice viene interpretata e quindi eseguita separatamente in una sequenza e viene rilevato un errore in una parte del codice che interromperà l'interpretazione del codice senza tradurre la serie successiva di codici.

Fonti: http://www.toptal.com/python/why-are-there-so-many-pythons http://www.engineersgarage.com/contribution/difference-between-compiler-and-interpreter


9
La tua definizione di "compilatore" non è corretta. Un compilatore non è mai stato sottoposto a compilazione in codice macchina. Un compilatore è semplicemente un traduttore da una lingua all'altra. Questo è il motivo per cui diciamo che Python "compila" in bytecode, Coffeescript "compila" in Javascript, e così via e così via.
Ricky Stewart,
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.