Автор Bluebird здесь.
Реализация обещаний V8 написана на JavaScript, а не на C. Весь JavaScript (включая собственный V8) скомпилирован в нативный код. Кроме того, написанный пользователем JavaScript оптимизируется, если это возможно (и того стоит), перед компиляцией в собственный код. Реализация обещаний - это то, что не принесет особой пользы от написания на C, а на самом деле только замедлит ее, потому что все, что вы делаете - это манипулируете объектами JavaScript и связью.
Реализация V8 просто не так оптимизирована, как bluebird, она для экземпляров выделяет массивы для обработчиков обещаний . Это занимает много памяти, когда каждому обещанию также приходится выделять пару массивов (эталонный тест создает в целом 80 000 обещаний, так что выделяется 160 000 неиспользуемых массивов). В действительности, 99,99% вариантов использования никогда не выполняют обещание более одного раза, поэтому оптимизация для этого общего случая дает значительные улучшения в использовании памяти.
Даже если V8 реализует те же оптимизации, что и bluebird, это все равно будет затруднено спецификацией. Тест должен использовать new Promise
(анти-паттерн в bluebird), так как в ES6 нет другого способа создать рутинное обещание. new Promise
это чрезвычайно медленный способ создания обещания, во-первых, функция executor выделяет замыкание, во-вторых, в качестве аргументов передается 2 отдельных замыкания. На каждое обещание выделяется 3 замыкания, но замыкание уже является более дорогим объектом, чем оптимизированное обещание.
Можно использовать Bluebird, promisify
которая позволяет выполнять множество оптимизаций и является гораздо более удобным способом использования API-интерфейсов обратного вызова, а также позволяет преобразовывать целые модули в модули на основе обещаний в одну строку ( promisifyAll(require('redis'));
).