Saya telah meneliti Penerjemah / Penyusun, kemudian saya menemukan JIT-Kompilasi - khususnya Mesin V8 Javascript Google Chrome.
Pertanyaan saya adalah -
- Bagaimana bisa lebih cepat daripada Interpretasi standar?
- Mengapa JIT-Compilation tidak digunakan?
Pemahaman Saya Saat Ini
Setiap Program Javascript dimulai sebagai kode sumber , kemudian, terlepas dari metode pelaksanaannya, pada akhirnya diterjemahkan ke kode mesin .
Baik Kompilasi-JIT dan Interpretasi harus mengikuti jalur ini, jadi bagaimana Kompilasi-JIT dapat lebih cepat (juga karena JIT dibatasi oleh waktu, tidak seperti Kompilasi-AOT)?Tampaknya JIT-Kompilasi adalah inovasi yang relatif lama , berdasarkan dari Artikel Kompilasi JIT Wikipedia .
"Kompiler JIT yang paling awal diterbitkan umumnya dikaitkan dengan bekerja pada LISP oleh McCarthy pada tahun 1960. "
"Smalltalk (c. 1983 ) memelopori aspek-aspek baru dari kompilasi JIT. Sebagai contoh, terjemahan ke kode mesin dilakukan sesuai permintaan, dan hasilnya di-cache untuk digunakan nanti. Ketika memori menjadi langka, sistem akan menghapus beberapa kode ini dan membuat ulang ketika dibutuhkan lagi. "
Jadi mengapa Javascript Diterjemahkan untuk memulai ?
Saya sangat bingung, dan saya telah melakukan banyak penelitian tentang ini, tetapi saya belum menemukan jawaban yang memuaskan.
Begitu jelas, jawaban singkat akan dihargai. Dan jika penjelasan tambahan tentang Penerjemah, JIT-Compiler, dll. Perlu dimasukkan, itu dihargai juga.
sumber
Jawaban:
Jawaban singkatnya adalah bahwa JIT memiliki waktu inisialisasi yang lebih lama, tetapi jauh lebih cepat dalam jangka panjang, dan JavaScript pada awalnya tidak dimaksudkan untuk jangka panjang.
Pada tahun 90-an, tipikal JavaScript di situs web akan berjumlah satu atau dua fungsi di header, dan beberapa kode tertanam langsung di
onclick
properti dan sejenisnya. Biasanya akan dijalankan dengan benar ketika pengguna mengharapkan penundaan pemuatan halaman yang sangat besar. Pikirkan validasi bentuk yang sangat mendasar atau utilitas matematika kecil seperti kalkulator bunga hipotek.Menafsirkan sesuai kebutuhan jauh lebih sederhana dan memberikan kinerja yang cukup memadai untuk kasus penggunaan saat itu. Jika Anda menginginkan sesuatu dengan kinerja jangka panjang, Anda menggunakan flash atau applet java.
Google maps pada tahun 2004 adalah salah satu aplikasi pembunuh pertama untuk penggunaan JavaScript yang berat. Itu membuka mata terhadap kemungkinan JavaScript, tetapi juga menyoroti masalah kinerjanya. Google menghabiskan beberapa waktu untuk mencoba mendorong browser untuk meningkatkan kinerja JavaScript mereka, kemudian akhirnya memutuskan kompetisi akan menjadi motivator terbaik, dan juga akan memberi mereka kursi terbaik di tabel standar browser. Hasilnya, Chrome dan V8 dirilis pada 2008. Sekarang, 11 tahun setelah Google Maps muncul, kami memiliki pengembang baru yang tidak ingat bahwa JavaScript dianggap tidak memadai untuk tugas semacam itu.
Katakanlah Anda memiliki fungsi
animateDraggedMap
. Mungkin butuh 500 ms untuk mengartikannya, dan 700 ms untuk JIT mengompilasinya. Namun, setelah kompilasi JIT, mungkin hanya membutuhkan 100 ms untuk benar-benar berjalan. Jika tahun 90-an dan Anda hanya memanggil fungsi sekali kemudian memuat ulang halaman, JIT tidak layak sama sekali. Jika hari ini dan Anda meneleponanimateDraggedMap
ratusan atau ribuan kali, tambahan 200 ms pada inisialisasi bukanlah apa-apa, dan itu dapat dilakukan di belakang layar sebelum pengguna bahkan mencoba menyeret peta.sumber
Dengan memahami apa yang terjadi pada saat runtime, dimungkinkan untuk membuat perubahan pada kode atau interpretasi dari kode yang memungkinkan untuk dieksekusi lebih cepat atau dikompilasi lebih baik daripada apa yang diketahui pada waktu kompilasi sebelumnya.
Cukup banyak yang dapat dikatakan tentang ini - ini adalah subjek dari sejumlah besar penelitian. Penjelasan saya sendiri di sini bahwa saya mulai menulis artinya jika dibandingkan dengan jawaban yang diberikan dalam Memahami perbedaan: juru bahasa tradisional, kompiler JIT, interpreter JIT dan kompiler AOT
Sederhananya, JavaScript pada awalnya tidak dikompilasi atau dilihat untuk JIT karena itu tidak pernah dimaksudkan untuk menjadi sesuatu yang kompleks atau penting.
Maksud asli Java Script adalah untuk menautkan ke applet Java pada halaman web. Kemampuan untuk mengklik pada beberapa tombol atau memasukkan nilai dalam bidang formulir dan kemudian bekerja di metode Java applet dapat dilihat di Meminta Metode Applet Dari Kode JavaScript . Itu juga memungkinkan, melalui JavaScript untuk menggunakan cara lain untuk memohon kode JavaScript dari applet .
Maksud asli JavaScript adalah untuk menautkan applet dan halaman html yang berisinya. Untuk tugas sekecil itu, seseorang tidak perlu kinerja hebat (jika Anda menginginkan kinerja, aktifkan metode applet yang JIT'ed).
Hanya setelah Netscape mulai melakukan pekerjaan yang signifikan dengan JavaScript sebagai bahasanya sendiri dan mempromosikannya untuk pengembangan (termasuk JavaScript Sisi Server di Netscape Enterprise Server - yang, secara tidak sengaja dilakukan sebelum kompilasi waktu), JavaScript mulai dikenal sebagai target serius. . Butuh bertahun-tahun setelah itu untuk alat yang diperlukan untuk membuatnya berguna.
sumber
JIT cepat untuk JavaScript, karena tidak mungkin untuk menghasilkan kode mesin cepat ketika Anda tidak tahu jenis variabel Anda.
Ketika Anda tidak memiliki informasi jenis, perhitungannya mahal. Sebagai contoh,
x + y
cukup rumit jika Anda tidak tahu apa-apa tentang x dan y. Mereka bisa bilangan bulat, ganda, string, atau bahkan objek di mana perhitungan ini memiliki efek samping. Karena kita tidak memiliki pengetikan statis, ini merupakan perhitungan yang mahal.
Dengan kompilasi just-in-time, kita dapat menggunakan informasi runtime dan mengubahnya menjadi komputasi yang lebih cepat. Saat runtime, V8 melacak tipe variabel. Jika kode di atas dijalankan beberapa kali dengan, katakanlah, string, kompiler dapat menjalankan instruksi yang lebih sederhana untuk penggabungan string. Jadi ketika kompiler mencapai
x + y
, alih-alih menjalankan banyak kode yang bercabang untuk berbagai jenis x dan y, kompiler dengan cepat memeriksa apakah kita memiliki string lagi, dan kemudian mengeksekusi hanya beberapa baris kode mesin yang secara khusus menggabungkan string.Dalam contoh, C ++ kompiler mengetahui tipe x dan y sebelumnya, karena kita harus mendeklarasikan variabel. Jadi itu dapat menghasilkan kode mesin yang dioptimalkan untuk string gabungan sebelum menjalankan kode.
sumber
1) Bagaimana bisa lebih cepat dari Interpretasi standar? Contoh yang dipikirkan adalah sebagai berikut; misalkan kita memiliki 2 aplikasi ApplicationCompiled dan ApplicationInterpreted. Kedua program ini melakukan hal yang persis sama, dan berbagi kode sumber yang sama. ApplicationCompiled membutuhkan waktu 6 detik untuk dikompilasi.
Katakanlah timing Skenario A adalah:
Jadi total ApplicationCompiled membutuhkan 10 detik untuk menjalankan Skenario A (kompilasi 6 detik, 4 detik berjalan) dan ApplicationInterpreted membutuhkan total 12 detik untuk berjalan. Saya tidak memiliki contoh khusus untuk menunjukkan kepada Anda, dan saya tidak yakin dalam kasus mana di atas akan benar - itu juga sangat tergantung pada seberapa cerdas penafsiran dan kompiler.
Jelas ini sangat disederhanakan, tetapi saya ide yang sama dapat diterapkan pada kompilasi / interpretasi JIT. Pertanyaan selanjutnya adalah "bagaimana kita menentukan - dengan biaya rendah - jika cabang ini harus dikompilasi atau ditafsirkan JIT"? Saya keluar dari liga saya di sini :)
2) Mengapa JIT-Compilation tidak digunakan? Tidak tahu, tapi saya ulangi itu hanya masalah sumber daya dan kematangan kemajuan yang tersedia dalam membuat bahasa yang sulit dioptimalkan seperti JavaScript menerapkan teknik canggih seperti ini. Mungkin ada banyak buah gantung yang lebih rendah pada saat itu.
sumber