Apakah Python Diartikan atau Dikompilasi?

76

Ini hanya bertanya-tanya yang saya miliki saat membaca tentang bahasa yang ditafsirkan dan dikompilasi.

Ruby tidak diragukan lagi merupakan bahasa yang ditafsirkan karena kode sumber diproses oleh juru bahasa pada titik eksekusi.
Sebaliknya C adalah bahasa yang dikompilasi, karena kita harus mengkompilasi kode sumber terlebih dahulu sesuai dengan mesin dan kemudian jalankan. Hasil ini jauh lebih cepat dieksekusi.

Sekarang datang ke Python :

  • Kode python ( somefile.py ) ketika diimpor membuat file ( somefile.pyc ) di direktori yang sama. Katakanlah impor dilakukan dalam modul python shell atau django. Setelah impor saya mengubah sedikit kode dan menjalankan fungsi yang diimpor lagi untuk menemukan bahwa itu masih menjalankan kode lama. Ini menunjukkan bahwa file * .pyc adalah file python yang dikompilasi mirip dengan executable yang dibuat setelah kompilasi file C, meskipun saya tidak dapat menjalankan file * .pyc secara langsung.
  • Ketika file python (somefile.py) dieksekusi secara langsung (./somefile.py atau python somefile.py) tidak ada file .pyc dibuat dan kode dieksekusi seperti menunjukkan perilaku yang ditafsirkan.

Ini menunjukkan bahwa kode python dikompilasi setiap kali itu diimpor dalam proses baru untuk membuat .pyc saat ditafsirkan ketika langsung dieksekusi.

Jadi, jenis bahasa apa yang harus saya pertimbangkan? Diterjemahkan atau Dikompilasi? Dan bagaimana efisiensinya dibandingkan dengan bahasa yang ditafsirkan dan dikompilasi?

Menurut halaman Interpreted Languages wiki , itu terdaftar sebagai bahasa yang dikompilasi dengan Virtual Machine Code, apa yang dimaksud dengan itu?

crodjer
sumber
1
Kapan ada keraguan apakah Ruby adalah bahasa yang ditafsirkan? Saat dikompilasi. :) macruby.org
mipadi
8
Perlu dicatat bahwa tidak ada bahasa modern yang ditafsirkan dalam arti yang ketat. Hampir semuanya dikompilasi menjadi bytecode.
Winston Ewert
@ Winston Ewert: bravo! Applesoft Basic (pada 1980-an) dikompilasi dengan byte-code. "Modern" dalam hal ini, berarti setiap bahasa yang ditafsirkan dalam memori hidup dengan satu-satunya pengecualian yang mungkin adalah beberapa implementasi Dartmouth Basic yang belum sempurna.
S.Lott
6
>> Sebaliknya C adalah bahasa yang dikompilasi << root.cern.ch/drupal/content/cint
igouy
3
@ S.Lott: Memanggil proses tokenization yang dilakukan oleh penerjemah Applesoft dan '80 -an BASIC melakukan "kompilasi bytecode" lebih dari sedikit tidak jujur. Ya, kode program yang dimasukkan oleh pengguna disimpan dalam memori dalam bentuk terkompresi, satu byte per kata yang dipesan, tetapi tidak ada yang dilakukan di luar itu sampai Anda mengetik RUN. Seolah-olah Anda memiliki kompiler yang melakukan langkah lexing dan kemudian menampilkan aliran token yang harus diulang setiap kali program dijalankan. Sama sekali tidak seperti kompilasi bytecode modern seperti yang dilakukan oleh, katakanlah javac, yang meliputi lexing, parsing, dan optimisasi.
dodgethesteamroller

Jawaban:

80

Perlu dicatat bahwa bahasa tidak ditafsirkan atau dikompilasi, melainkan implementasi bahasa baik menafsirkan atau mengkompilasi kode. Anda mencatat bahwa Ruby adalah "bahasa yang ditafsirkan", tetapi Anda dapat mengkompilasi Ruby à la MacRuby , jadi itu tidak selalu merupakan bahasa yang ditafsirkan.

Hampir setiap implementasi Python terdiri dari juru bahasa (bukan kompiler). The .pycfile yang Anda lihat adalah kode byte untuk mesin virtual Python (mirip dengan Jawa .classfile). Mereka tidak sama dengan kode mesin yang dihasilkan oleh kompiler C untuk arsitektur mesin asli. Beberapa implementasi Python, bagaimanapun, terdiri dari kompiler just-in-time yang akan mengkompilasi kode byte Python ke dalam kode mesin asli.

(Saya mengatakan "hampir setiap" karena saya tidak tahu ada kompiler mesin asli untuk Python, tapi saya tidak ingin mengklaim bahwa tidak ada di mana pun.)

mipadi
sumber
Bergantung pada definisi Anda, kompiler mesin asli untuk Python ada. Beberapa hanya mengkompilasi subset python. Lainnya mengimplementasikan semua python tetapi menggunakan API python untuk benar-benar melakukan operasi yang tidak dapat dilakukan dalam C.
Winston Ewert
Saya pikir Anda benar-benar menggambarkan bahwa Python adalah apa yang saya sebut 'semi-dikompilasi', atau sebenarnya dapat dikompilasi penuh. Dengan semi-dikompilasi maksud saya karena biasanya dikompilasi ke file .pyc 'bahasa menengah' yang digunakan oleh Mesin Virtual Python, biasanya dijalankan dari bentuk 'semi-dikompilasi' ini, yang umumnya membuat kode lebih cepat daripada interpretasi run-time sederhana dari kode yang ditafsirkan. Menariknya, kode semi-dikompilasi kadang-kadang bisa lebih cepat daripada kode yang dikompilasi secara asli (misalnya C # umumnya lebih cepat dari C ++).
Chris Halcrow
5
Cython mengkompilasi kode Python ke C sehingga dapat dikompilasi sebagai objek bersama.
greyfade
Membedakan kode byte dan kode mesin dengan cara ini cukup sewenang-wenang. Java dikompilasi: kompiler javac menghasilkan file kelas yang berisi instruksi level rendah yang dapat dieksekusi, baik dalam mesin virtual (misalnya hotspot) atau langsung oleh perangkat keras (misalnya pada prosesor ARM dengan ekstensi Jazelle). Sejauh yang saya tahu, tidak ada alasan teknis arsitektur prosesor serupa tidak dapat dirancang untuk secara langsung menjalankan instruksi python vm.
Jules
@ Jules Secara kebetulan, kode Jython sebenarnya dikompilasi ke file .class yang saya percaya digunakan kembali sampai Anda memodifikasi sumber py.
JimmyJames
35

Python akan jatuh di bawah kode byte yang ditafsirkan. .pykode sumber pertama dikompilasi ke kode byte sebagai .pyc. Kode byte ini dapat diartikan (CPython resmi), atau JIT dikompilasi (PyPy). Kode sumber Python ( .py) dapat dikompilasi ke kode byte yang berbeda juga seperti IronPython (.Net) atau Jython (JVM). Ada beberapa implementasi bahasa Python. Yang resmi adalah kode byte yang ditafsirkan. Ada byte kode implementasi JIT dikompilasi juga.

Untuk perbandingan kecepatan berbagai implementasi bahasa, Anda dapat mencoba di sini .

ayah
sumber
thanx untuk info. Menurut tolok ukur kinerja python adalah cara turun!
crodjer
1
Tautan yang saya berikan dengan sangat jelas menyatakan bahwa ini adalah tolok ukur cacat implementasi bahasa . Python seharusnya tidak menjadi pilihan bahasa Anda jika Anda terlalu khawatir tentang kinerja eksekusi. Jika Anda masih ingin membandingkan, bandingkan bahasa yang serupa. Kode byte yang diartikan CPython resmi sebanding dengan atau lebih cepat dari JIT yang dikompilasi Ruby.
aufather
1
@ jase21 - "Rencana saya untuk tahun 2006 adalah untuk port teknik yang diterapkan di Psyco ke PyPy. PyPy akan memungkinkan kita untuk membangun spesialisasi JIT yang lebih fleksibel, lebih mudah untuk bereksperimen, dan tanpa biaya tambahan harus tetap selaras dengan evolusi dari bahasa Python. " psyco.sourceforge.net/introduction.html
igouy
1
@ jase21 - "membuat kode python berjalan lebih cepat daripada bagian penghitung C" - Apakah kita seharusnya hanya mengambil kata-kata Anda untuk itu?
igouy
3
Tautan dalam jawaban terputus.
Basilevs
11

Dikompilasi vs ditafsirkan dapat membantu dalam beberapa konteks, tetapi ketika diterapkan dalam pengertian teknis, itu adalah dikotomi yang salah.

Kompiler (dalam arti luas) adalah penerjemah . Ini menerjemahkan program A ke program B dan untuk eksekusi di masa depan menggunakan mesin M.

Seorang juru bahasa (dalam arti luas) adalah seorang pelaksana . Ini adalah mesin M yang menjalankan program A. Meskipun kami biasanya mengecualikan dari definisi ini mesin fisik (atau mesin non-fisik yang bertindak seperti yang fisik). Tetapi dari perspektif teoretis, perbedaan itu agak sewenang-wenang.


Sebagai contoh, ambil re.compile. Ini "mengkompilasi" suatu regex ke bentuk peralihan, dan bahwa bentuk peralihan ditafsirkan / dievaluasi / dieksekusi.


Pada akhirnya, itu tergantung pada level abstraksi apa yang Anda bicarakan, dan apa yang Anda pedulikan. Orang mengatakan "dikompilasi" atau "ditafsirkan" sebagai deskripsi luas dari bagian yang paling menarik dari proses, tetapi sebenarnya sebagian besar setiap program dikompilasi (diterjemahkan) dan ditafsirkan (dieksekusi) dengan satu atau lain cara.

CPython (implementasi paling populer dari bahasa Python) sebagian besar menarik untuk mengeksekusi kode. Jadi CPython biasanya digambarkan sebagai ditafsirkan. Padahal ini label yang longgar.

Paul Draper
sumber
7

Kode Mesin Virtual adalah versi yang lebih ringkas dari kode sumber asli (kode byte). Masih perlu ditafsirkan oleh mesin virtual, karena tidak ada kode mesin. Akan lebih mudah dan lebih cepat untuk menguraikan daripada kode asli yang ditulis oleh manusia.

Beberapa mesin virtual menghasilkan kode mesin saat menafsirkan kode mesin virtual untuk pertama kalinya (hanya dalam kompilasi waktu - JIT). Doa berikut akan menggunakan kode mesin ini secara langsung, yang mengarah pada eksekusi yang lebih cepat.

Sejauh yang saya tahu Ruby> = 1.9 menggunakan mesin virtual seperti Python juga.

Program Lenny
sumber
5

Runtime Python menjalankan kode objek khusus (kode byte) pada mesin virtual.

Proses kompilasi mengubah kode sumber menjadi kode objek.

Untuk mempercepat, kode objek (atau kode byte, jika Anda mau) disimpan pada disk, sehingga dapat digunakan kembali saat berikutnya program dijalankan.

ykombinator
sumber