En este punto de referencia , el conjunto tarda 4 veces más en completarse con las promesas de ES6 en comparación con las promesas de Bluebird, y utiliza 3,6 veces más memoria.
¿Cómo puede una biblioteca de JavaScript ser mucho más rápida y ligera que la implementación nativa de v8 escrita en C? Las promesas de Bluebird tienen exactamente la misma API que las promesas de ES6 nativas (además de un montón de métodos de utilidad adicionales).
¿La implementación nativa está mal escrita o hay algún otro aspecto que me falta?
javascript
performance
io.js
callum
fuente
fuente
new
operador porque PromiseMeSpeedJS no lo utilizanew
.Respuestas:
Bluebird autor aquí.
V8 promete que la implementación está escrita en JavaScript, no C. Todo JavaScript (incluido el propio V8) se compila en código nativo. Además, el JavaScript escrito por el usuario está optimizado, si es posible (y vale la pena), antes de compilarlo en código nativo. La implementación de las promesas es algo que no se beneficiaría mucho o no se escribiría en C, de hecho, solo lo haría más lento porque todo lo que está haciendo es manipular los objetos JavaScript y la comunicación.
La implementación de V8 simplemente no está tan optimizada como bluebird, por ejemplo, asigna matrices para controladores de promesas . Esto toma mucha memoria cuando cada promesa también tiene que asignar un par de matrices (el punto de referencia crea 80k promesas generales, por lo que se asignan 160k matrices no utilizadas). En realidad, el 99,99% de los casos de uso nunca ramifican una promesa más de una vez, por lo que la optimización para este caso común aumenta enormemente el uso de la memoria.
Incluso si V8 implementara las mismas optimizaciones que bluebird, todavía se vería obstaculizado por la especificación. El punto de referencia tiene que usar
new Promise
(un antipatrón en bluebird) ya que no hay otra forma de crear una promesa de raíz en ES6.new Promise
es una forma extremadamente lenta de crear una promesa, primero la función ejecutora asigna un cierre, en segundo lugar se pasan 2 cierres separados como argumentos. Son 3 cierres asignados por promesa, pero un cierre ya es un objeto más costoso que una promesa optimizada.Bluebird puede usarlo, lo
promisify
que permite muchas optimizaciones y es una forma mucho más conveniente de consumir API de devolución de llamada y permite la conversión de módulos completos en módulos basados en promesas en una línea (promisifyAll(require('redis'));
).fuente
new Promise
mejorar la creación de instancias para que sea menos costosa (como no crear 3 cierres por instancia)?Promise.resolve()
para crear una "promesa raíz"?Promise.resolve()
o lo que sea), pero es una implementación muy básica, ¡y su existencia no debería desanimarte con herramientas más serias relacionadas con promesas como bluebird!