Bagaimana cara kerja Chrome V8? Dan mengapa JavaScript tidak dikompilasi dengan JIT?


19

Saya telah meneliti Penerjemah / Penyusun, kemudian saya menemukan JIT-Kompilasi - khususnya Mesin V8 Javascript Google Chrome.

Pertanyaan saya adalah -

  1. Bagaimana bisa lebih cepat daripada Interpretasi standar?
  2. Mengapa JIT-Compilation tidak digunakan?


Pemahaman Saya Saat Ini

  1. 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)?

  2. 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.


2
# 2 dan # 3 dapat dijawab, tetapi "Bagaimana Cara Kerja Mesin Chrome V8?" tanpa kualifikasi apa pun terlalu luas; satu-satunya jawaban yang benar adalah tautan ke kode sumber V8. Apakah Anda bermaksud menanyakan sesuatu yang lebih spesifik tentang V8? (jika tidak, sebaiknya hapus bagian pertanyaan itu)
Ixrec

Pada pandangan kedua, satu-satunya titik saya bertanya # 1 adalah untuk memahami # 2, jadi saya akan menghapusnya. Terima kasih atas masukannya.
Anton Paras

Ini tidak disebutkan dalam jawaban lain tetapi kompilasi JIT sulit. Ini bukan hal yang mudah untuk dilakukan karena kesalahan yang dihasilkan dari kompilasi JIT menghasilkan segfault bukannya kesalahan - program macet bukannya melemparkan kesalahan di konsol. Ya, untuk programmer C kompeten yang nyaman dengan gdb ini bukan masalah. Tetapi hampir semua programmer C kompeten nyaman dengan gdb dibayar untuk bekerja pada proyek lain. Beberapa bahasa lain seperti Perl dan Ruby masih belum memiliki penerjemah JIT utama.
Slebetman

Jika Anda bertanya-tanya. Saya berbicara tentang ini dari perspektif pengembang inti / pemelihara untuk bahasa pemrograman. Selama beberapa tahun saya dipekerjakan untuk mempertahankan bahasa pemrograman Ferite. Salah satu daftar keinginan yang kami miliki adalah untuk mengimplementasikan JIT. Itu tidak pernah terjadi - kami malah pindah untuk pergi. PHP baru-baru ini mendapat kompiler JIT (HVVM) berkat Facebook yang mengeluarkan cukup uang untuk mewujudkannya.
Slebetman

Jawaban:


43

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 onclickproperti 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 menelepon animateDraggedMapratusan atau ribuan kali, tambahan 200 ms pada inisialisasi bukanlah apa-apa, dan itu dapat dilakukan di belakang layar sebelum pengguna bahkan mencoba menyeret peta.


2

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.


1
Tidak, Javascript tidak terkait dengan Java. Dan applet Java adalah bytecode JVM.
Basile Starynkevitch

@BasileStarynkevitch JavaScript dirancang untuk bekerja dengan applet Java di halaman dusun - bertindak sebagai perekat antara dom html dan metode yang terdapat dalam objek Java. Ini bukan dan tidak pernah dimaksudkan sebagai Jawa.

JavaScript pada awalnya disebut ECMAScript (atau sesuatu seperti itu) dan tidak ada hubungannya dengan Java. Bagaimana itu disebut JavaScript adalah subjek penelitian terpisah untuk mereka yang tertarik. Ini telah menyebabkan kebingungan sejak saat itu.
cepat,

1
@quickly_now dan masih tc39.github.io/ecma262
caub

Iya. Dan untuk beberapa alasan aneh ketika saya menunjukkan bahwa di atas saya telah dipilih untuk itu!
quick_now

1

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.


0

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:

  • Untuk ApplicationCompiled: 4 detik
  • Untuk ApplicationInterpreted: 12 detik

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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.