Mengapa mengkompilasi kode Python?

241

Mengapa Anda mengkompilasi skrip Python? Anda dapat menjalankannya langsung dari file .py dan berfungsi dengan baik, jadi apakah ada keunggulan kinerja atau sesuatu?

Saya juga memperhatikan bahwa beberapa file dalam aplikasi saya dapat dikompilasi ke dalam .pyc sementara yang lain tidak, mengapa demikian?

ryeguy
sumber
Anda juga dapat mencatat bahwa, termasuk startup yang lebih cepat dari aplikasi Anda, Anda juga mendapatkan keamanan, jika Anda tidak dapat membagikan kode Anda jika itu merupakan rahasia perusahaan.
Please_Dont_Bully_Me_SO_Lords
@PSyLoCKe Anda benar-benar tidak. Bytecode Python benar-benar dapat dibaca, karena kompiler tidak perlu mengaburkannya untuk mengoptimalkannya. (Bukan berarti itu banyak mengoptimalkan ...)
wizzwizz4
1
Alasan beberapa file dikompilasi secara otomatis adalah karena mereka diimpor; misalnya, jika Anda menggunakan import mylib.py, Python akan mengkompilasi mylib.pysehingga importpernyataan di masa depan berjalan sedikit lebih cepat. Jika nanti Anda berubah mylib.py, maka itu akan dikompilasi ulang saat berikutnya diimpor (Python menggunakan tanggal file untuk melihat bahwa ini terjadi.)
fyngyrz

Jawaban:

270

Ini dikompilasi ke bytecode yang dapat digunakan banyak, jauh, lebih cepat.

Alasan beberapa file tidak dikompilasi adalah karena skrip utama, yang Anda panggil python main.pydikompilasi ulang setiap kali Anda menjalankan skrip. Semua skrip yang diimpor akan dikompilasi dan disimpan di disk.

Penambahan penting oleh Ben Blank :

Perlu dicatat bahwa saat menjalankan skrip yang dikompilasi memiliki waktu startup yang lebih cepat (karena tidak perlu dikompilasi), skrip tidak berjalan lebih cepat.

Georg Schölly
sumber
260
Perlu dicatat bahwa saat menjalankan skrip yang dikompilasi memiliki waktu startup yang lebih cepat (karena tidak perlu dikompilasi), skrip tidak berjalan lebih cepat.
Ben Blank
24
Kesalahpahaman umum. Terima kasih telah berbagi.
Matpie
1
Selain tidak membutuhkan kompilasi, file .pyc hampir selalu lebih kecil. Apalagi jika Anda banyak berkomentar. Salah satu tambang saya adalah 28419 sebagai .py, tetapi hanya 17879 sebagai .pyc - jadi waktu muat juga lebih baik. Akhirnya, Anda dapat mengkompilasi skrip tingkat atas dengan cara ini: python -m compileall myscript.py
fyngyrz
1
Apakah ada perbedaan dalam konsumsi memori? Saya sedang menguji Python pada perangkat tertanam berdasarkan mips cpu dengan hanya 64MB RAM, jadi apakah ada keuntungan dalam penggunaan memori ketika memulai versi kompilasi dari skrip python?
valentt
1
@valentt: Mungkin tidak. Saya tidak tahu banyak tentang internal Python, tapi saya tidak berpikir bahwa mem-parsing bytecode membutuhkan banyak memori dalam Python. Saya tidak dapat memikirkan sesuatu yang membutuhkan banyak memori untuk mengingat suatu keadaan.
Georg Schölly
80

File .pyc adalah Python yang telah dikompilasi ke byte-code. Python secara otomatis menjalankan file .pyc jika menemukannya dengan nama yang sama dengan file .py yang Anda panggil.

"An Introduction to Python" mengatakan ini tentang kompilasi file Python:

Suatu program tidak berjalan lebih cepat ketika itu dibaca dari file '.pyc' atau '.pyo' daripada ketika itu dibaca dari file '.py'; satu-satunya hal yang lebih cepat tentang file '.pyc' atau '.pyo' adalah kecepatannya.

Keuntungan menjalankan file .pyc adalah bahwa Python tidak harus mengeluarkan biaya kompilasi sebelum menjalankannya. Karena Python akan mengkompilasi ke byte-code sebelum menjalankan file .py, seharusnya tidak ada peningkatan kinerja selain itu.

Berapa banyak peningkatan yang bisa Anda dapatkan dari menggunakan file .pyc yang telah dikompilasi? Itu tergantung pada apa yang dilakukan skrip. Untuk skrip yang sangat singkat yang hanya mencetak "Hello World," kompilasi dapat merupakan persentase besar dari total waktu startup-dan-lari. Tetapi biaya mengkompilasi skrip relatif terhadap total run time berkurang untuk skrip yang berjalan lebih lama.

Skrip yang Anda beri nama pada baris perintah tidak pernah disimpan ke file .pyc. Hanya modul yang dimuat oleh skrip "utama" yang disimpan dengan cara itu.

Bill Karwin
sumber
3
Dalam banyak kasus sulit untuk melihat perbedaannya, tetapi saya memiliki file python khusus dengan lebih dari 300.000 baris. (Ini adalah kumpulan perhitungan matematika yang dihasilkan oleh skrip lain untuk pengujian) Diperlukan 37 detik untuk mengkompilasi, dan hanya 2 detik untuk dieksekusi.
wojtow
54

Plus:

Pertama: kebingungan yang ringan dan dapat dikalahkan.

Kedua: jika kompilasi menghasilkan file yang jauh lebih kecil, Anda akan mendapatkan waktu pemuatan yang lebih cepat. Bagus untuk web.

Ketiga: Python dapat melewati langkah kompilasi. Lebih cepat pada beban awal. Bagus untuk CPU dan web.

Keempat: semakin banyak Anda berkomentar, semakin kecil file .pycatau .pyoakan dibandingkan dengan .pyfile sumber .

Kelima: pengguna akhir dengan hanya satu .pycatau .pyofile di tangan jauh lebih kecil kemungkinannya untuk memberi Anda bug yang disebabkan oleh perubahan yang tidak dikembalikan yang lupa untuk Anda beri tahu.

Keenam: jika Anda membidik sistem tertanam, mendapatkan file ukuran yang lebih kecil untuk disematkan mungkin merupakan nilai tambah yang signifikan, dan arsitekturnya stabil sehingga kelemahannya, yang dirinci di bawah, tidak ikut berperan.

Kompilasi tingkat atas

Sangat berguna untuk mengetahui bahwa Anda dapat mengkompilasi file sumber python tingkat atas ke dalam .pycfile dengan cara ini:

python -m py_compile myscript.py

Ini menghilangkan komentar. Itu meninggalkan docstringsutuh. Jika Anda ingin menyingkirkannya docstringsjuga (Anda mungkin ingin serius memikirkan mengapa Anda melakukan itu), maka kompilasi dengan cara ini sebagai gantinya ...

python -OO -m py_compile myscript.py

... dan Anda akan mendapatkan .pyo file alih-alih .pycfile; sama-sama dapat didistribusikan dalam hal fungsi esensial kode, tetapi lebih kecil dengan ukuran stripped-out docstrings(dan kurang mudah dipahami untuk pekerjaan berikutnya jika sudah layak docstringsdi tempat pertama). Tapi lihat kekurangannya tiga, di bawah.

Perhatikan bahwa python menggunakan tanggal .pyfile, jika ada, untuk memutuskan apakah harus mengeksekusi .pyfile sebagai lawan dari file .pycatau .pyo--- jadi edit file .py Anda, dan .pycatau.pyo sudah usang dan manfaat apa pun yang Anda peroleh hilang. Anda perlu mengkompilasi ulang untuk mendapatkan .pycatau .pyomanfaat kembali lagi, seperti mungkin.

Kekurangan:

Pertama: Ada "cookie ajaib" .pycdan .pyofile yang menunjukkan arsitektur sistem tempat file python dikompilasi. Jika Anda mendistribusikan salah satu file ini ke lingkungan dari tipe yang berbeda, itu akan rusak. Jika Anda mendistribusikan .pycatau .pyotanpa terkait .pyuntuk mengkompilasi ulang atautouch sehingga menggantikan .pycatau .pyo, pengguna akhir tidak dapat memperbaikinya, baik.

Kedua: Jika docstrings dilewati dengan menggunakan -OOopsi baris perintah seperti yang dijelaskan di atas, tidak ada yang bisa mendapatkan informasi itu, yang dapat membuat penggunaan kode lebih sulit (atau tidak mungkin.)

Ketiga: -OOOpsi Python juga mengimplementasikan beberapa optimasi -Osesuai opsi baris perintah; ini dapat menyebabkan perubahan dalam operasi. Optimalisasi yang diketahui adalah:

  • sys.flags.optimize = 1
  • assert pernyataan dilewati
  • __debug__ = Salah

Keempat: jika Anda dengan sengaja membuat skrip python Anda dapat dieksekusi dengan sesuatu sesuai urutan #!/usr/bin/pythonpada baris pertama, ini akan dihapus .pycdan .pyofile serta fungsinya hilang.

Kelima: agak jelas, tetapi jika Anda mengkompilasi kode Anda, tidak hanya penggunaannya dapat terpengaruh, tetapi potensi orang lain untuk belajar dari pekerjaan Anda berkurang, seringkali sangat parah.

fyngyrz
sumber
10

Ada peningkatan kinerja dalam menjalankan python yang dikompilasi. Namun ketika Anda menjalankan file .py sebagai modul yang diimpor, python akan mengkompilasi dan menyimpannya, dan selama file .py tidak berubah, selalu akan menggunakan versi yang dikompilasi.

Dengan bahasa yang saling terkait saat file digunakan prosesnya terlihat seperti ini:
1. File diproses oleh interpeter.
2. File dikompilasi
3. Kode kompilasi dijalankan.

jelas dengan menggunakan kode pra-kompilasi Anda dapat menghilangkan langkah 2, ini berlaku python, PHP dan lainnya.

Berikut posting blog yang menarik menjelaskan perbedaan http://julipedia.blogspot.com/2004/07/compiled-vs-interpreted-languages.html
Dan inilah entri yang menjelaskan proses kompilasi Python http://effbot.org/zone /python-compile.htm

UnkwnTech
sumber
9

Seperti yang telah disebutkan, Anda bisa mendapatkan peningkatan kinerja dari kode python yang dikompilasi menjadi bytecode. Ini biasanya ditangani oleh python sendiri, hanya untuk skrip yang diimpor.

Alasan lain Anda mungkin ingin mengkompilasi kode python Anda, bisa jadi untuk melindungi kekayaan intelektual Anda agar tidak disalin dan / atau dimodifikasi.

Anda dapat membaca lebih lanjut tentang ini di dokumentasi Python .

Simon B. Jensen
sumber
2
Dalam hal melindungi kode Anda - kompilasi tidak akan banyak membantu. Kompilasi kebingungan - tetapi seseorang dengan keinginan akan mendapatkan kode Anda.
Josh Smeaton
1
@ josh itu selalu mungkin, jika seseorang dapat mengakses memori atau menonton instruksi ke cpu, dengan waktu yang cukup dan akan mereka dapat membangun kembali aplikasi Anda.
UnkwnTech
5
Setuju, namun seperti dikatakan Unkwntech, itu akan selalu mungkin, jika orang itu cukup bertekad. Tapi aku yakin itu akan cukup dalam kebanyakan situasi, di mana Anda biasanya hanya ingin membatasi orang-orang dari "memperbaiki" kode Anda ...
Simon B. Jensen
Bahasa yang dikompilasi menjadi bytecode umumnya tidak terlalu sulit untuk dikompilasi ulang kecuali Anda mengambil langkah-langkah tambahan untuk mengaburkan mereka - hanya mengkompilasi secara umum tidak akan cukup.
EJoshuaS
7

Pasti ada perbedaan kinerja saat menjalankan skrip yang dikompilasi. Jika Anda menjalankan .pyskrip normal , mesin mengkompilasinya setiap kali dijalankan dan ini membutuhkan waktu. Pada mesin-mesin modern ini hampir tidak terlihat tetapi ketika skrip tumbuh mungkin menjadi lebih banyak masalah.

matpie
sumber
7

Sesuatu yang tidak tersentuh adalah kompilasi sumber-ke-sumber . Sebagai contoh,nuitka menerjemahkan kode Python ke C / C ++, dan mengkompilasinya ke kode biner yang langsung berjalan pada CPU, bukannya bytecode Python yang berjalan pada mesin virtual yang lebih lambat.

Ini dapat menyebabkan peningkatan kecepatan yang signifikan, atau ini akan memungkinkan Anda bekerja dengan Python sementara lingkungan Anda bergantung pada kode C / C ++.

pengguna258532
sumber
4

Kami menggunakan kode terkompilasi untuk mendistribusikan kepada pengguna yang tidak memiliki akses ke kode sumber. Pada dasarnya untuk menghentikan programmer yang tidak berpengalaman secara tidak sengaja mengubah sesuatu atau memperbaiki bug tanpa memberi tahu kami.

DrBwts
sumber
2

Yap, kinerja adalah alasan utama dan, sejauh yang saya tahu, satu-satunya alasan.

Jika beberapa file Anda tidak dikompilasi, mungkin Python tidak dapat menulis ke file .pyc, mungkin karena izin direktori atau sesuatu. Atau mungkin file yang belum dikompilasi tidak pernah dimuat ... (skrip / modul hanya dikompilasi saat pertama kali dimuat)

David Z
sumber
1

Pemula menganggap Python dikompilasi karena file .pyc. File .pyc adalah bytecode yang dikompilasi, yang kemudian ditafsirkan. Jadi jika Anda sudah menjalankan kode Python Anda sebelumnya dan memiliki file .pyc berguna, itu akan berjalan lebih cepat untuk kedua kalinya, karena tidak harus mengkompilasi ulang bytecode

penyusun: Compiler adalah bagian dari kode yang menerjemahkan bahasa tingkat tinggi ke dalam bahasa mesin

Penerjemah: Penerjemah juga mengonversi bahasa tingkat tinggi menjadi setara biner yang dapat dibaca mesin. Setiap kali ketika seorang juru bahasa mendapatkan kode bahasa tingkat tinggi untuk dieksekusi, itu mengubah kode menjadi kode perantara sebelum mengubahnya menjadi kode mesin. Setiap bagian dari kode ditafsirkan dan kemudian dieksekusi secara terpisah dalam urutan dan kesalahan ditemukan di bagian kode itu akan menghentikan interpretasi kode tanpa menerjemahkan set kode berikutnya.

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

Pemula
sumber
9
Definisi "kompiler" Anda salah. Kompiler belum pernah dikompilasi ke kode mesin. Kompiler hanyalah penerjemah dari satu bahasa ke bahasa lain. Inilah sebabnya mengapa kita mengatakan bahwa Python "mengkompilasi" untuk bytecode, Coffeescript "mengkompilasi" ke Javascript, dan seterusnya dan seterusnya.
Ricky Stewart