Apa yang menghalangi Ruby, Python untuk mendapatkan kecepatan Javascript V8? [Tutup]

261

Apakah ada fitur Ruby / Python yang menghalangi implementasi optimasi (mis. Inline caching ) yang dimiliki mesin V8?

Python dikembangkan bersama oleh orang-orang Google sehingga tidak boleh diblokir oleh paten perangkat lunak.

Atau ini lebih merupakan masalah sumber daya yang dimasukkan ke dalam proyek V8 oleh Google.

Greg Dan
sumber
6
Introspeksi dan operator yang berlebihan mungkin yang besar, tapi saya tidak tahu JS cukup baik untuk memberi Anda jawaban nyata. Proyek PyPy kemungkinan kesempatan terbaik Python untuk mencapai kecepatan jenis JS.
ncoghlan
11
Apakah Anda memiliki contoh di mana PyPy lebih lambat dari V8 kecuali untuk penembakan bahasa komputer yang bollocks lengkap (lihat saja betapa berbedanya hal-hal diimplementasikan dalam bahasa yang berbeda di sana). Atau itu hanya bidang distorsi kenyataan google?
fijal
3
V8 tidak cukup normal dengan Python. Tunggu hingga V8 harus mengimplementasikan 1,8 Javascript spec untuk membuat perbandingan yang lebih baik. Dan pada saat itu saya yakin bahwa seseorang akan berusaha untuk mengimplementasikan PyPy di ​​atas mesin V8 menggantikan Javascript.
Michael Dillon
14
Mengapa Anda begitu yakin V8 lebih cepat dari Python atau Ruby? Apa?
jcoffland
6
V8 benar-benar lebih cepat daripada Python / Ruby. Lakukan segala jenis tolok ukur yang Anda inginkan, dari microbenchmark sederhana hingga aplikasi dunia nyata komprehensif yang ditulis secara idiomatis di kedua lingkungan tersebut. Ini urutan besarnya lebih cepat untuk sebagian besar operasi bahasa-asli (mis. Hal-hal yang tidak bisa didelegasikan ke kode C dengan Python).
Hejazzman

Jawaban:

519

Apa yang menghalangi Ruby, Python untuk mendapatkan kecepatan Javascript V8?

Tidak ada.

Baiklah, oke: uang. (Dan waktu, orang, sumber daya, tetapi jika Anda memiliki uang, Anda dapat membelinya.)

V8 memiliki tim insinyur yang brilian, sangat terspesialisasi, sangat berpengalaman (dan dengan demikian dibayar sangat tinggi) mengerjakannya, yang memiliki pengalaman puluhan tahun (saya berbicara secara individu - secara kolektif lebih seperti berabad-abad) dalam menciptakan eksekusi kinerja tinggi mesin untuk bahasa OO dinamis. Mereka pada dasarnya adalah orang yang sama yang juga menciptakan Sun HotSpot JVM (di antara banyak lainnya).

Lars Bak, pengembang utama, telah benar-benar bekerja pada VM selama 25 tahun (dan semua VM tersebut mengarah ke V8), yang pada dasarnya adalah seluruh hidupnya (profesional). Beberapa orang yang menulis Ruby VM bahkan belum berusia 25 tahun.

Apakah ada fitur Ruby / Python yang menghalangi implementasi optimasi (mis. Inline caching) yang dimiliki mesin V8?

Mengingat setidaknya IronRuby, JRuby, MagLev, MacRuby dan Rubinius memiliki monomorfik (IronRuby) atau caching inline polimorfik, jawabannya jelas tidak.

Implementasi Ruby modern sudah melakukan banyak optimasi. Misalnya, untuk operasi tertentu, Hashkelas Rubinius lebih cepat daripada kelas YARV. Sekarang, ini tidak terdengar sangat menarik sampai Anda menyadari bahwa Hashkelas Rubinius diimplementasikan dalam 100% Ruby murni, sementara YARV diimplementasikan dalam 100% tangan-dioptimalkan C.

Jadi, setidaknya dalam beberapa kasus, Rubinius dapat menghasilkan kode yang lebih baik daripada GCC!

Atau ini lebih merupakan masalah sumber daya yang dimasukkan ke dalam proyek V8 oleh Google.

Iya. Bukan hanya Google. Silsilah kode sumber V8 berusia 25 tahun sekarang. Orang-orang yang bekerja pada V8 juga menciptakan Self VM (hingga hari ini salah satu mesin eksekusi bahasa OO dinamis tercepat yang pernah dibuat), Animorphic Smalltalk VM (hingga hari ini salah satu mesin eksekusi Smalltalk tercepat yang pernah dibuat), HotSpot JVM (JVM tercepat yang pernah dibuat, mungkin periode VM tercepat) dan OOVM (salah satu VM Smalltalk paling efisien yang pernah dibuat).

Faktanya, Lars Bak, pengembang utama V8, mengerjakan semua hal itu, ditambah beberapa lainnya.

Jörg W Mittag
sumber
1
Bisakah kita memiliki beberapa referensi literatur tentang "Mengingat bahwa setidaknya IronRuby, JRuby, MagLev, MacRuby dan Rubinius memiliki monomorfik (IronRuby) atau caching inline polimorfik, jawabannya jelas tidak." silahkan?
WDRust
14
SpiderMonkey memiliki kinerja yang sebanding, jadi bagaimana Mozilla melakukannya? Uang mereka sangat terbatas ..
Salman von Abbas
8
@SalmanPK: ini bukan VM pertama mereka, dan ada orang-orang pintar yang bekerja di Mozilla juga.
Matthieu M.
3
@SalmanPK, miguel: Mozilla membuat JS VM mereka setidaknya sebagian dengan reverse engineering V8. blog.mozilla.org/dmandelin/2010/09/08/presenting-jagermonkey
Ian
2
@Ian V8 adalah open source (lisensi BSD), jadi tidak perlu merekayasa balik, lihat saja apa yang mereka lakukan.
dbkk
78

Ada lebih banyak dorongan untuk mengoptimalkan penerjemah JavaScript, oleh karena itu kami melihat begitu banyak sumber daya dimasukkan di antara Mozilla, Google, dan Microsoft. JavaScript harus diunduh, diuraikan, dikompilasi, dan dijalankan dalam waktu nyata sementara manusia (yang biasanya tidak sabar) sedang menunggunya, itu harus dijalankan SAAT seseorang berinteraksi dengan itu, dan melakukan ini di klien-end yang tidak terkendali lingkungan yang bisa berupa komputer, telepon, atau pemanggang roti. Ini HARUS efisien untuk berjalan di bawah kondisi ini secara efektif.

Python dan Ruby dijalankan di lingkungan yang dikontrol oleh pengembang / penyebar. Server gemuk atau sistem desktop umumnya di mana faktor pembatasnya adalah hal-hal seperti memori atau disk I / O dan bukan waktu eksekusi. Atau di mana optimisasi non-mesin seperti caching dapat dimanfaatkan. Untuk bahasa-bahasa ini, mungkin lebih masuk akal untuk fokus pada fitur bahasa dan pustaka yang ditetapkan pada pengoptimalan kecepatan.

Manfaat sampingan dari ini adalah bahwa kami memiliki dua mesin JavaScript open source berkinerja tinggi yang dapat dan sedang dirancang ulang untuk semua jenis aplikasi seperti Node.js.


sumber
43

Bagian yang baik dari itu berkaitan dengan komunitas. Python dan Ruby sebagian besar tidak memiliki dukungan perusahaan. Tidak ada yang dibayar untuk bekerja di Python dan Ruby penuh waktu (dan mereka terutama tidak dibayar untuk bekerja di CPython atau MRI sepanjang waktu). V8, di sisi lain, didukung oleh perusahaan IT paling kuat di dunia.

Selain itu, V8 bisa lebih cepat karena satu-satunya hal yang penting bagi orang-orang V8 adalah penerjemah - mereka tidak memiliki perpustakaan standar untuk dikerjakan, tidak ada masalah tentang desain bahasa. Mereka hanya menulis penerjemah. Itu dia.

Ini tidak ada hubungannya dengan hukum kekayaan intelektual. Python juga tidak dikembangkan bersama oleh orang-orang Google (pembuatnya bekerja di sana bersama beberapa komuter lain, tetapi mereka tidak dibayar untuk mengerjakan Python).

Kendala lain untuk kecepatan Python adalah Python 3. Adopsinya tampaknya menjadi perhatian utama pengembang bahasa - sampai-sampai mereka telah membekukan pengembangan fitur bahasa baru sampai implementasi lain menyusul.

Ke detail teknis, saya tidak tahu banyak tentang Ruby, tetapi Python memiliki sejumlah tempat di mana optimisasi dapat digunakan (dan Unladen Swallow, proyek Google, mulai mengimplementasikannya sebelum menggigit debu). Berikut adalah beberapa optimasi yang mereka rencanakan . Saya bisa melihat Python mendapatkan kecepatan V8 di masa depan jika JIT a la PyPy diimplementasikan untuk CPython, tetapi sepertinya tidak mungkin untuk tahun-tahun mendatang (fokus saat ini adalah adopsi Python 3, bukan JIT).

Banyak juga yang merasa bahwa Ruby dan Python dapat mengambil manfaat yang sangat besar dengan menghapus kunci juru bahasa global masing-masing .

Anda juga harus memahami bahwa Python dan Ruby keduanya bahasa yang jauh lebih berat daripada JS - mereka menyediakan jauh lebih banyak cara perpustakaan standar, fitur bahasa, dan struktur. Sistem kelas orientasi objek saja menambah banyak bobot (dalam cara yang baik, saya pikir). Saya hampir menganggap Javascript sebagai bahasa yang dirancang untuk disematkan, seperti Lua (dan dalam banyak hal, mereka mirip). Ruby dan Python memiliki serangkaian fitur yang lebih kaya, dan ekspresifitas itu biasanya akan datang dengan mengorbankan kecepatan.

Rafe Kettler
sumber
3
Sebenarnya moratorium fitur baru telah dicabut sejak rilis terbaru Python 3.2.
jd.
2
+1, tetapi bukankah membeku pada fitur bahasa baru berarti lebih banyak waktu untuk dihabiskan untuk optimasi?
Andrew Grimm
1
@Andrew jika saja. Fokusnya adalah mempercepat Jython, IronPython, dan PyPy, menunggu perpustakaan dikonversi ke Python 3, dan menginjili Python 3.
Rafe Kettler
2
"Sistem kelas orientasi objek saja menambah banyak bobot" - JavaScript JavaScript modern seperti V8 memiliki kelas, mereka hanya tersirat. Sama seperti di Python, Anda tidak harus secara eksplisit mengetikkan variabel dalam JavaScript. Anda tidak harus mengetikkan kelas secara eksplisit. VM cukup pintar untuk melewati kode Anda dan mengekstrak kelas.
Benjamin Gruenbaum
1
Seperti yang saya mengerti, V8 adalah kompiler JIT daripada penerjemah ... Saya cukup yakin ada perbedaan antara keduanya. Mungkin tidak ... saya tidak tahu.
Luke
24

Kinerja tampaknya tidak menjadi fokus utama pengembang Python inti, yang tampaknya merasa bahwa "cukup cepat" cukup baik, dan bahwa fitur yang membantu pemrogram menjadi lebih produktif lebih penting daripada fitur yang membantu komputer menjalankan kode lebih cepat.

Memang, bagaimanapun, ada proyek Google (sekarang ditinggalkan), unladen-walet , untuk menghasilkan juru bahasa Python lebih cepat yang kompatibel dengan juru bahasa standar. PyPy adalah proyek lain yang bermaksud menghasilkan Python yang lebih cepat. Ada juga Psyco , cikal bakal PyPy, yang dapat memberikan peningkatan kinerja ke banyak skrip Python tanpa mengubah seluruh penerjemah, dan Cython , yang memungkinkan Anda menulis perpustakaan C berkinerja tinggi untuk Python menggunakan sesuatu yang sangat mirip dengan sintaksis Python.

baik hati
sumber
13

Pertanyaan yang menyesatkan. V8 adalah implementasi JIT (compiler just in time) dari JavaScript dan dalam implementasi non-browser Node.js yang paling populer itu dibangun di sekitar sebuah loop acara. CPython bukan JIT & tidak terjadi. Tapi ini ada di Python paling umum di proyek PyPy - sebuah CPYthon 2.7 (dan segera menjadi 3.0+) JIT yang kompatibel. Dan ada banyak perpustakaan server yang terjadi seperti Tornado misalnya. Tes dunia nyata ada antara PyPy menjalankan Tornado vs Node.js dan perbedaan kinerja sedikit.

Handloomweaver
sumber
3
+1 untuk menyebutkan Tornado . Meskipun berjalan dengan kecepatan yang sebanding dengan Node.js, gen.enginemodulnya bersama dengan generator Python dan yieldpernyataan ( sejak 2.5 !!! dapat mendefinisikan ulang pengkodean asinkron Anda.
Lukas Bünger
1
Sejak posting Anda, pypy merilis versi stabil 3.x yang didukung (dan terus meningkatkan dukungan, tentu saja): morepypy.blogspot.fr/2014/06/pypy3-231-fulcrum.html
Zeograd
9

Saya baru saja membahas pertanyaan ini dan ada juga alasan teknis besar untuk perbedaan kinerja yang tidak disebutkan. Python memiliki ekosistem ekstensi perangkat lunak yang sangat besar, tetapi sebagian besar ekstensi ini ditulis dalam bahasa C atau bahasa tingkat rendah lainnya untuk kinerja dan sangat terikat dengan API CPython.

Ada banyak teknik terkenal (JIT, pengumpul sampah modern, dll) yang dapat digunakan untuk mempercepat implementasi CPython tetapi semua akan membutuhkan perubahan besar pada API, memecah sebagian besar ekstensi dalam proses. CPython akan lebih cepat, tetapi banyak hal yang membuat Python begitu menarik (tumpukan perangkat lunak yang luas) akan hilang. Contohnya, ada beberapa implementasi Python lebih cepat di luar sana tetapi mereka memiliki sedikit daya tarik dibandingkan dengan CPython.

Jason McCampbell
sumber
9

Karena prioritas desain yang berbeda dan tujuan penggunaan kasus saya percaya.

Secara umum tujuan utama scripting (alias dinamis) bahasa adalah untuk menjadi "perekat" antara panggilan fungsi asli. Dan fungsi asli ini harus a) mencakup area yang paling kritis / sering digunakan dan b) seefektif mungkin.

Berikut adalah contoh: jQuery semacam menyebabkan iOS Safari untuk membekukan Pembekuan ada disebabkan oleh penggunaan berlebihan dari panggilan get-by-pemilih. Jika get-by-selector akan diimplementasikan dalam kode asli dan efektif itu tidak akan menjadi masalah sama sekali.

Pertimbangkan demo ray-tracer yang sering digunakan demo untuk demonstrasi V8. Dalam dunia Python dapat diimplementasikan dalam kode asli karena Python menyediakan semua fasilitas untuk ekstensi asli. Tetapi dalam ranah V8 (kotak sisi klien) Anda tidak memiliki pilihan lain selain membuat VM menjadi [sub] seefektif mungkin. Maka satu-satunya opsi lihat implementasi ray-tracer di sana adalah dengan menggunakan kode skrip.

Jadi beda prioritas dan motivasi.

Dalam Sciter saya telah membuat tes dengan mengimplementasikan inti jQurey penuh yang cukup banyak secara native. Pada tugas-tugas praktis seperti ScIDE (IDE terbuat dari HTML / CSS / Script) saya percaya solusi seperti itu bekerja secara signifikan lebih baik daripada optimasi VM.

c-senyum
sumber
5

Seperti yang telah disebutkan orang lain, Python memiliki kompiler JIT yang performan dalam bentuk PyPy .

Membuat tolok ukur yang berarti selalu halus, tetapi kebetulan saya memiliki tolok ukur sederhana K-means yang ditulis dalam berbagai bahasa - Anda dapat menemukannya di sini . Salah satu kendala adalah bahwa semua bahasa harus menerapkan algoritma yang sama dan harus berusaha untuk menjadi sederhana dan idiomatik (sebagai lawan dioptimalkan untuk kecepatan). Saya telah menulis semua implementasinya, jadi saya tahu saya belum selingkuh, walaupun saya tidak dapat mengklaim untuk semua bahasa bahwa apa yang saya tulis adalah idiomatik (saya hanya memiliki pengetahuan yang lewat tentang beberapa di antaranya).

Saya tidak mengklaim kesimpulan pasti, tetapi PyPy adalah salah satu implementasi tercepat yang saya dapatkan, jauh lebih baik daripada Node. CPython, sebaliknya, berada di ujung peringkat paling lambat.

Andrea
sumber
5

Pernyataan itu tidak sepenuhnya benar

Sama seperti V8 hanyalah implementasi untuk JS, CPython hanyalah satu implementasi untuk Python. Pypy memiliki kinerja yang cocok dengan V8 .

Juga, ada masalah kinerja yang dirasakan: karena V8 secara asli tidak memblokir, dev Web mengarah ke proyek yang lebih berkinerja karena Anda menyimpan IO menunggu. Dan V8 terutama digunakan untuk dev Web di mana IO adalah kuncinya, sehingga mereka membandingkannya dengan proyek serupa. Tetapi Anda dapat menggunakan Python di banyak, banyak area selain web dev. Dan Anda bahkan dapat menggunakan ekstensi C untuk banyak tugas, seperti perhitungan ilmiah atau enkripsi, dan mengolah data dengan perf yang menyala-nyala.

Tetapi di web, sebagian besar proyek Python dan Ruby yang populer sedang diblokir. Python, khususnya, memiliki warisan standar WSGI yang sinkron, dan kerangka kerja seperti Django yang terkenal didasarkan padanya.

Anda dapat menulis Python asinkron (seperti dengan Twisted, Tornado, gevent atau asyncio) atau Ruby. Tapi itu tidak sering dilakukan. Alat terbaik masih memblokir.

Namun, mereka adalah beberapa alasan mengapa implementasi default di Ruby dan Python tidak secepat V8.

Pengalaman

Seperti Jorg W Mittag tunjukkan, orang-orang yang bekerja pada V8 adalah jenius VM. Python adalah dev oleh sekelompok orang yang penuh gairah, sangat baik dalam banyak domain, tetapi tidak mengkhususkan diri dalam tuning VM.

Sumber daya

Yayasan Python Software memiliki sedikit uang: kurang dari 40rb dalam setahun untuk berinvestasi di Python. Ini agak gila ketika Anda berpikir pemain besar seperti Google, Facebook atau Apple semuanya menggunakan Python, tapi itu kebenarannya: kebanyakan pekerjaan dilakukan secara gratis. Bahasa yang mendukung Youtube dan ada sebelum Jawa telah dibuat oleh para relawan.

Mereka adalah sukarelawan yang berdedikasi dan berdedikasi, tetapi ketika mereka mengidentifikasi mereka membutuhkan lebih banyak jus di lapangan, mereka tidak dapat meminta 300rb untuk menyewa spesialis tingkat atas untuk bidang keahlian ini. Mereka harus mencari-cari seseorang yang akan melakukannya secara gratis.

Sementara ini berhasil, itu berarti Anda harus sangat berhati-hati dengan prioritas Anda. Oleh karena itu, sekarang kita perlu melihat:

Tujuan

Bahkan dengan fitur modern terbaru, menulis Javascript sangat buruk. Anda memiliki masalah pelingkupan, sangat sedikit koleksi, manipulasi string dan array yang mengerikan, hampir tidak ada stdlist selain tanggal, matematika dan regex, dan tidak ada gula sintaksis bahkan untuk operasi yang sangat umum.

Namun di V8, Anda punya kecepatan.

Ini karena, kecepatan adalah tujuan utama Google, karena ini menjadi penghambat untuk perenderan halaman di Chrome.

Dalam Python, kegunaan adalah tujuan utama. Karena itu hampir tidak pernah menjadi hambatan pada proyek. Sumber daya yang langka di sini adalah waktu pengembang. Ini dioptimalkan untuk pengembang.

e-satis
sumber
1

Karena implementasi JavaScript tidak perlu peduli dengan kompatibilitas bindings mereka.

Sampai saat ini satu-satunya pengguna implementasi JavaScript adalah browser web. Karena persyaratan keamanan, hanya vendor browser web yang memiliki hak istimewa untuk memperluas fungsionalitas dengan menulis binding ke runtimes. Dengan demikian tidak perlu menjaga agar API C dari binding tetap kompatibel, diizinkan untuk meminta pengembang browser web memperbarui kode sumber mereka saat runtime JavaScript berevolusi; mereka bekerja bersama-sama. Bahkan V8, yang merupakan latecomer untuk game, dan juga dipimpin oleh pengembang yang sangat berpengalaman, telah mengubah API karena menjadi lebih baik.

OTOH Ruby digunakan (terutama) di sisi server. Banyak ekstensi ruby ​​populer ditulis sebagai binding C (pertimbangkan driver RDBMS). Dengan kata lain, Ruby tidak akan pernah berhasil tanpa mempertahankan kompatibilitas.

Saat ini, perbedaannya masih ada sampai batas tertentu. Pengembang yang menggunakan node.js mengeluh bahwa sulit untuk menjaga ekstensi asli mereka tetap kompatibel, karena V8 mengubah API dari waktu ke waktu (dan itulah salah satu alasan node.js telah bercabang dua). Ruby IIRC masih mengambil pendekatan yang jauh lebih konservatif dalam hal ini.

Kazuho
sumber
1

V8 cepat karena JIT, Crankshaft, tipe inferencer dan kode yang dioptimalkan data. Pointer yang ditandai, penandaan ganda NaN. Dan tentu saja itu tidak optimalisasi kompiler normal di tengah.

Mesin ruby, python dan perl yang polos tidak melakukan keduanya, hanya optimasi dasar kecil.

Satu-satunya vm utama yang mendekati adalah luajit, yang bahkan tidak melakukan inferensi tipe, pelipatan konstan, penandaan NaN atau bilangan bulat, tetapi menggunakan kode kecil dan struktur data yang sama, tidak setemak bahasa yang buruk. Dan bahasa dinamis prototipe saya, ramuan dan p2 memiliki fitur yang sama seperti luajit, dan mengungguli v8. Dengan sistem jenis opsional, "pengetikan bertahap", Anda dapat dengan mudah mengungguli v8, karena Anda dapat mem-bypass crankshaft. Lihat panah.

Backend dioptimalkan dikenal, seperti pypy atau jruby masih menderita berbagai teknik over-engineering.

rurban
sumber
Lihat juga github.com/rahul080327/medusa
Günter Zöchbauer