Dalam tolok ukur ini , paket membutuhkan waktu 4 kali lebih lama untuk dilengkapi dengan janji ES6 dibandingkan dengan janji Bluebird, dan menggunakan memori 3,6 kali lebih banyak.
Bagaimana pustaka JavaScript bisa lebih cepat dan lebih ringan daripada implementasi asli v8 yang ditulis dalam C? Janji Bluebird memiliki API yang persis sama dengan janji ES6 asli (ditambah banyak metode utilitas tambahan).
Apakah implementasi asli hanya ditulis dengan buruk, atau ada aspek lain yang saya lewatkan?
javascript
performance
io.js
callum
sumber
sumber
new
operator karena PromiseMeSpeedJS tidak menggunakannew
.Jawaban:
Penulis bluebird di sini.
Implementasi V8 berjanji ditulis dalam JavaScript bukan C. Semua JavaScript (termasuk milik V8) dikompilasi ke kode asli. Selain itu, JavaScript yang ditulis pengguna dioptimalkan, jika mungkin (dan layak), sebelum dikompilasi dengan kode asli. Menjanjikan implementasi adalah sesuatu yang tidak akan mendapat banyak manfaat atau sama sekali dari ditulis dalam C, pada kenyataannya itu hanya akan membuatnya lebih lambat karena semua yang Anda lakukan adalah memanipulasi objek JavaScript dan komunikasi.
Implementasi V8 tidak seoptimal bluebird, contohnya mengalokasikan array untuk penangan janji . Ini membutuhkan banyak memori ketika setiap janji juga harus mengalokasikan beberapa array (Benchmark menciptakan keseluruhan 80 ribu janji sehingga 160r dialokasikan array yang tidak digunakan). Pada kenyataannya, 99,99% kasus penggunaan tidak pernah menumbuhkan janji lebih dari sekali sehingga mengoptimalkan untuk kasus umum ini mendapatkan peningkatan penggunaan memori yang sangat besar.
Bahkan jika V8 mengimplementasikan optimasi yang sama seperti bluebird, itu masih akan terhalang oleh spesifikasi. Patokan harus menggunakan
new Promise
(anti-pola di bluebird) karena tidak ada cara lain untuk membuat janji root di ES6.new Promise
adalah cara yang sangat lambat untuk membuat janji, pertama fungsi pelaksana mengalokasikan penutupan, kedua melewati 2 penutupan terpisah sebagai argumen. Itu adalah 3 penutupan yang dialokasikan per janji tetapi penutupan sudah merupakan objek yang lebih mahal daripada janji yang dioptimalkan.Bluebird dapat menggunakan
promisify
yang memungkinkan banyak optimasi dan merupakan cara yang jauh lebih nyaman untuk mengonsumsi API panggilan balik dan memungkinkan konversi seluruh modul menjadi modul berbasis janji dalam satu baris (promisifyAll(require('redis'));
).sumber
new Promise
atau meningkatkan instantiasi untuk membuatnya lebih murah (seperti tidak membuat 3 penutupan per instance)?Promise.resolve()
untuk membuat "janji root"?Promise.resolve()
atau apa pun), tetapi ini adalah implementasi yang sangat mendasar, dan keberadaannya seharusnya tidak membuat Anda menunda menggunakan alat yang berhubungan dengan janji yang lebih serius seperti bluebird!