Bagaimana jenis dicek dalam interpreter / kompiler bahasa dinamis, seperti JavaScript?

11

Dalam bahasa dinamis, seperti JavaScript atau Python, jenis variabel ditentukan saat runtime. Ini adalah salah satu alasan mengapa mereka lebih lambat dari bahasa yang diketik seperti Java.

Bagaimana pemeriksaan tipe dilakukan? Apa alasan penting proses ini lambat?


sumber
Mereka tidak lebih lambat karena mereka dinamis, mereka lebih lambat karena lebih sulit untuk membuatnya lebih cepat. JavaScript sebenarnya yang paling optimal dan cukup cepat.
Derek Litz

Jawaban:

5

Ada kebingungan dalam pertanyaan itu.

Ada asumsi bahwa pengecekan tipe lambat, yang belum tentu demikian.

Pertanyaannya juga tampaknya membingungkan proses pengiriman tipe dengan memeriksa jenis , dan mereka adalah dua hal yang berbeda. Salah satunya adalah proses yang dilakukan pada saat run time, yang lainnya proses pada waktu kompilasi. Saya menduga pertanyaannya adalah benar-benar bertanya tentang jenis pengiriman.

Ini adalah jenis pengiriman yang dapat memperkenalkan overhead pada saat runtime, karena perhitungan menghabiskan waktu dengan instruksi yang memutuskan, secara dinamis, tindakan apa yang harus diambil, berdasarkan pada jenis nilai yang dilihatnya pada waktu berjalan. misalnya dalam bahasa yang dinamis, jika saya menerapkan "+" pada dua hal, saya bisa berarti penambahan numerik, atau penggabungan string, jadi saya perlu menghabiskan waktu melihat apa yang ada di tangan untuk memutuskan apa yang harus dilakukan. Ada strategi evaluasi yang dapat mengurangi biaya pengiriman dinamis. (misalnya, melacak JIT)

Berkenaan dengan melakukan pengecekan tipe dalam JavaScript, lihat: http://www.cs.brown.edu/~sk/Publications/Papers/Published/gsk-flow-typing-theory/ . Untuk gambaran umum yang lebih umum tentang cara kerja checker jenis, buku teks bahasa pemrograman standar akan membahas algoritme. Misalnya, http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/

dyoo
sumber
Saya juga menulis survei kecil tentang melacak JIT dan bahasa dinamis di hashcollision.org/comprehensive/tracing.pdf
Interpreter Javascript membawa bit tag dengan setiap nilai untuk pengiriman jenis. Bisakah Anda menguraikan sedikit tentang ini? Misalnya, apa gunanya bit tag? Apakah sedikit sesuai dengan tipe?
Konsep tipe tidak selalu terhubung dengan representasi. Kita mungkin memiliki konsep tipe 'mil' vs tipe 'kilometer', dan masuk akal untuk memiliki bahasa yang dapat mendeteksi secara statis, pada waktu kompilasi, apakah perhitungan secara tidak benar menerapkan operasi pada nilai-nilai yang mengacaukan tipe. . Anda mungkin membayangkan bahwa mereka memiliki representasi yang sama, dan jika kompiler dapat, pada waktu kompilasi, menjamin bahwa mereka tidak pernah dicampur, maka tidak ada alasan mengapa nilai-nilai akan membutuhkan pelabelan tambahan dalam representasi.
1
Melanjutkan: tetapi sering, terutama dalam bahasa yang dinamis, Anda ingin mewakili nilai dari berbagai jenis. Ada beberapa cara untuk melakukan diskriminasi ini. Jenis tag umum, tetapi ada teknik lain. Misalnya, Anda dapat menempatkan jenis tertentu di wilayah memori yang diblokir. Lihat "Mewakili Informasi Jenis dalam Bahasa yang Diketik Secara Dinamis." lambda-the-ultimate.org/node/3912 untuk survei teknik representasi yang komprehensif.
7

Pada dasarnya, dalam bahasa yang tidak diketik, setiap referensi menunjuk ke objek yang berisi tipe dan nilai. Misalnya var a = 3menunjuk ke sebuah instance yang berisi nilai 3 dan tipe int, jika Anda membuat a = "bla", referensi diperbarui ke sebuah instance yang berisi string "bla" dan string tipe, objek lama dibuang, dll ...

Ini lambat karena setiap kali operasi (mis. a + b) Harus dilakukan pada tipe dasar ini, runtime harus terlebih dahulu melakukan dereferensi objek, periksa apakah tipenya kompatibel, lakukan operasi, buat objek baru.

Sebaliknya, a + bdalam C ++ atau Java memeriksa pada waktu kompilasi bahwa jenisnya valid dan kompatibel, maka a dan b disimpan sebagai nilai langsung (bukan referensi), dan penambahan adalah operasi prosesor sederhana pada nilai-nilai ini.

Tentu saja, ini semua sangat teoretis. Dalam praktiknya, banyak optimasi dapat dilakukan pada proses ini untuk menghindari sebagian besar overhead, dan bahasa yang diketik secara dinamis bisa menjadi sangat cepat.

solendil
sumber
1
Trik seperti cache inline polimorfik dapat sangat meningkatkan kinerja. Tulisan David Ungar (Self) dan Eliot Miranda (Squeak, Visual Works Smalltalk virtual) paling informatif, berkenaan dengan kinerja bahasa yang dinamis.
Frank Shearar
0

Setiap nilai disimpan bersama dengan tipenya, yang perlu diperiksa terlebih dahulu. Konversi juga mengatakan dari string ke nomor melalui inspeksi, on the fly.

Joop Eggen
sumber
Yap, ini dia, ini hanya pemeriksaan runtime, tidak ada yang mewah.
anon