在此基准测试中,与Bluebird Promise相比,套件完成ES6 Promise的时间要长4倍,并且使用的内存是3.6倍。
JavaScript库如何比用C编写的v8本机实现更快,更轻巧?Bluebird Promise与本机ES6 Promise具有完全相同的API(以及大量额外的实用程序方法)。
是本机实现编写得不好,还是我缺少其他方面?
在此基准测试中,与Bluebird Promise相比,套件完成ES6 Promise的时间要长4倍,并且使用的内存是3.6倍。
JavaScript库如何比用C编写的v8本机实现更快,更轻巧?Bluebird Promise与本机ES6 Promise具有完全相同的API(以及大量额外的实用程序方法)。
是本机实现编写得不好,还是我缺少其他方面?
Answers:
蓝鸟作者在这里。
V8承诺实现是用JavaScript而不是C 编写的。所有JavaScript(包括V8自己的JavaScript)都被编译为本机代码。此外,在可能的情况下(并且值得)对用户编写的JavaScript进行优化,然后再编译为本机代码。使用C编写承诺的实现并不会带来任何好处或根本没有任何好处,实际上,这只会使它变慢,因为您所做的只是操纵JavaScript对象和通信。
V8实现根本不如bluebird优化,它为实例分配了promises处理程序的数组。当每个promise还必须分配几个数组时,这会占用大量内存(基准创建了总共80k个promise,因此分配了160k个未使用的数组)。实际上,99.99%的用例从未多次承诺过,因此针对此常见用例进行优化可以获得巨大的内存使用改进。
即使V8实现了与bluebird相同的优化,它仍然会受到规范的阻碍。基准测试必须使用new Promise
(蓝鸟中的反模式),因为没有其他方法可以在ES6中创建根本承诺。new Promise
创建承诺的方法非常慢,首先执行程序函数分配一个闭包,其次将两个单独的闭包作为参数传递给它。每个promise分配了3个闭包,但是闭包已经比优化promise更昂贵。
Bluebird可以使用promisify
它进行大量优化,并且是使用回调API的更为便捷的方法,并且可以将整个模块转换为一行(promisifyAll(require('redis'));
)中的基于Promise的模块。
new Promise
或改善实例化以使其更便宜(例如不为每个实例创建3个闭包)?
Promise.resolve()
用来创建“根本承诺”吗?
Promise.resolve()
或其他操作而导入库),但这是一个非常基本的实现,它的存在不应该让您使用更严重的与Promise相关的工具(如bluebird)!