Mengapa tidak ada kompiler python ke kode mesin asli?

25

Seperti yang saya mengerti, penyebab perbedaan kecepatan antara bahasa yang dikompilasi dan python adalah, bahwa kode pertama mengkompilasi semua jalan ke kode mesin asli, sedangkan python mengkompilasi ke bytecode python, untuk ditafsirkan oleh PVM. Saya melihat bahwa cara ini kode python dapat digunakan pada beberapa sistem operasi (setidaknya dalam kebanyakan kasus), namun saya tidak mengerti, mengapa tidak ada kompiler tambahan (dan opsional) untuk python, yang mengkompilasi dengan cara yang sama seperti kompiler tradisional . Ini akan diserahkan kepada programmer untuk memilih, mana yang lebih penting bagi mereka; kinerja atau kinerja multiplatform pada mesin asli. Secara umum; mengapa tidak ada bahasa yang bisa berperilaku baik sebagai dikompilasi dan ditafsirkan?

pengguna2986898
sumber
4
Ada adalah . Haskell juga dapat berperilaku sebagai dikompilasi atau ditafsirkan melalui GHCI
toasted_flakes
C ++ juga memiliki juru bahasa . Dan mungkin banyak bahasa lain memiliki kedua implementasi tersebut.
Claudio
2
Sebenarnya, dengan memilih IronPythong ( ironpython.net ) dan mengkompilasi kode IL yang dihasilkan dengan menggunakan "ngen" ( msdn.microsoft.com/de-de/library/6t9t5wcf%28v=vs.110%29.aspx ) ada adalah cara untuk mengkompilasi Python ke kode mesin asli. Bukannya saya telah menguji rantai alat itu.
Doc Brown
10
Seseorang dapat menulis kompiler Python-ke-asli. Mereka tidak terlalu menarik karena mereka tidak benar-benar meningkatkan kinerja dengan selisih yang signifikan, kecuali mereka benar-benar menerapkan bahasa yang terlihat seperti Python tetapi jauh lebih terbatas. Saya sebelumnya menjelaskan di tempat lain mengapa.

Jawaban:

29

Tidak. Alasan mengapa ada perbedaan kecepatan antara bahasa seperti Python dan C ++ adalah karena bahasa yang diketik secara statis memberikan kompiler banyak informasi tentang struktur program dan data yang memungkinkannya untuk mengoptimalkan perhitungan dan akses memori. Karena C ++ tahu bahwa variabel bertipe int, ia dapat menentukan cara optimal untuk memanipulasi variabel itu bahkan sebelum program dijalankan. Di Python di sisi lain, runtime tidak tahu nilai apa yang ada dalam variabel sampai garis tercapai oleh penerjemah. Ini sangat penting untuk struktur, di mana dalam C ++, kompiler dapat dengan mudah mengetahui ukuran struktur dan setiap lokasi bidangnya di dalam memori selama kompilasi. Ini memberinya kekuatan besar dalam memprediksi bagaimana data dapat digunakan dan memungkinkannya mengoptimalkan menurut prediksi tersebut.

Untuk mengkompilasi bahasa seperti Python secara efektif, Anda perlu:

  1. Pastikan bahwa struktur data statis selama pelaksanaan program. Ini bermasalah karena Python memiliki eval dan metaclasses. Keduanya memungkinkan untuk mengubah struktur program berdasarkan input dari program. Ini adalah salah satu hal yang memberi Python kekuatan ekspresif seperti itu.
  2. Pilih jenis semua variabel, struktur, dan kelas dari kode sumber itu sendiri. Meskipun mungkin sampai taraf tertentu, sistem dan algoritma tipe statis akan sangat kompleks sehingga hampir tidak mungkin untuk diterapkan dengan cara yang dapat digunakan. Anda bisa melakukannya untuk subset bahasa, tetapi jelas tidak untuk seluruh rangkaian fitur bahasa.
Euforia
sumber
6
Perlu dicatat bahwa ini memang membuat masalah menjadi sulit , tetapi bukan tidak mungkin. sbcl mengkompilasi Common Lisp yang juga dinamis, memiliki eval, dan banyak hal lain untuk membuat penulis kompiler sedih. Ini tidak setingkat gcc, tapi tentu saja lebih cepat daripada juru bahasa CPython.
Daniel Gratzer
3
@ Jozefg kataku efektif mengkompilasi. Bukan hanya kompilasi. Python juga memiliki kompiler Cython yang menghasilkan kode asli. Intinya adalah kompiler yang tidak dapat melakukan sebagian kecil dari optimasi yang dapat dikompilasi oleh kompiler untuk bahasa yang diketik secara statis. Dan ketika Anda membandingkan kinerja, bandingkan dengan kompilasi C ++ dan tidak diinterpretasikan Python.
Euforia
2
Yah sebenarnya, Anda akan terkejut apa yang bisa dilakukan sbcl. Game tolok ukur ini menunjukkan game ini berjalan secepat Java, hampir secepat GHC, dan dalam 1x hingga 10x C. Ini tidak lambat menurut standar apa pun. Ya, tipe dinamis menghambat kompilasi sampai batas tertentu, tetapi tidak sebanyak yang Anda pikirkan.
Daniel Gratzer
3
Membandingkan kecepatan python yang diinterpretasikan ke python yang dikompilasi menarik dalam dirinya sendiri. Berhentilah mengatakan "gunakan C ++". Mungkin Anda sudah memiliki kode yang ditulis dengan Python. Mungkin kodenya lebih mudah ditulis dengan python. Siapa peduli. Yang saya pedulikan adalah kecepatan 1,5x (apa pun itu). Itu bisa membuat perbedaan besar.
Thomas Eding
3
Dengan kata lain, jika Anda ingin mengkompilasi, pilih bahasa lain yang disetel untuk itu, seperti C ++ atau Pascal.
Please_Dont_Bully_Me_SO_Lords
0

Dua konsep mungkin membantu kita memahami lebih baik mengapa Python dikompilasi ke kode mesin asli "mungkin" tidak berjalan secepat kompilasi C atau bahasa yang dikompilasi lainnya. Mereka disebut mengikat awal dan mengikat terlambat.

Saya harus mulai dengan mengatakan saya bukan ahli Python, dan saya datang ke situs ini secara tidak sengaja. Tapi saya suka situs ini.

Seperti disebutkan dalam respons lain di sini, kompiler C ++ dapat mengetahui banyak tentang program dan membuat keputusan tentang operasi mana yang akan digunakan untuk struktur data tertentu. Sebagai contoh jika dua variabel integer perlu ditambahkan bersama-sama, kompiler tahu mereka adalah integer asli, lebar 32 bit misalnya dan dapat menambahkannya bersama dengan satu instruksi "ADD". Jadi kompilasi instruksi ADD ke dalam kode. Terkunci dan tidak dapat diubah saat program sedang berjalan. Itu mengikat awal.

Di sisi lain dalam bahasa seperti Python kita bisa mengharapkan program untuk membuang berbagai jenis data bersama dengan cara yang kompleks. Sekarang kompiler tidak tahu apakah 2 variabel kita adalah bilangan bulat, float, string atau daftar. Jadi ia harus mengkompilasi kode yang menentukan informasi itu pada waktu menjalankan dan memilih operasi yang benar ketika program sedang berjalan. Ini mengikat terlambat dan kita dapat memahami bahwa akan ada hit kinerja untuk melakukan pekerjaan ekstra saat program sedang berjalan. Ini adalah harga yang Anda bayar untuk membiarkan opsi-opsi itu terbuka dalam bahasa seperti Python tetapi itu memberikan fleksibilitas run-time maksimum.

pengguna214354
sumber
-4

Saya pikir ini lebih berkaitan dengan spesifikasi Python itu sendiri, alasan yang sama Anda tidak dapat mengkompilasi C # ke kode mesin. Bahasa spesifik sebenarnya akan membuat program Anda bermasalah bahkan jika itu mungkin karena sifat bahasa. Mengapa tidak belajar bahasa C saja? Jauh lebih mudah daripada C ++ dan sedikit lebih maju dari Python tetapi masih bisa didekati.

Tajam
sumber
5
C # dapat langsung menuju ke kode mesin: Bahasa Antara Menengah Umum: Kompilasi Ahead of Time - "Lingkungan eksekusi yang kompatibel dengan CLI juga datang dengan opsi untuk melakukan kompilasi Ahead-of-time (AOT) dari sebuah perakitan untuk membuatnya dieksekusi lebih cepat dengan menghapus proses JIT saat runtime. Dalam .NET Framework ada alat khusus yang disebut Native Image Generator (NGEN) yang melakukan AOT. Di Mono ada juga opsi untuk melakukan AOT. "