Nesse benchmark , o conjunto leva quatro vezes mais tempo para concluir as promessas do ES6 em comparação com as promessas do Bluebird e usa 3,6 vezes mais memória.
Como uma biblioteca JavaScript pode ser muito mais rápida e mais leve que a implementação nativa da v8, escrita em C? As promessas do Bluebird têm exatamente a mesma API que as promessas nativas do ES6 (além de vários métodos de utilidade extras).
A implementação nativa está mal escrita ou há algum outro aspecto disso que estou perdendo?
javascript
performance
io.js
callum
fonte
fonte
new
operador, porque o PromiseMeSpeedJS não usanew
.Respostas:
Autor Bluebird aqui.
A implementação do V8 promete ser escrita em JavaScript, não em C. Todo o JavaScript (incluindo o próprio V8) é compilado no código nativo. Além disso, o JavaScript escrito pelo usuário é otimizado, se possível (e vale a pena), antes de ser compilado no código nativo. A implementação de promessas é algo que não beneficiaria muito ou nada de ser escrito em C, na verdade, só o tornaria mais lento porque tudo que você está fazendo é manipular objetos e comunicação JavaScript.
A implementação da V8 simplesmente não é tão otimizada quanto o bluebird, por exemplo, aloca matrizes para manipuladores de promessas . Isso requer muita memória quando cada promessa também precisa alocar algumas matrizes (a referência cria promessas gerais de 80k, de modo que são 160k matrizes não utilizadas alocadas). Na realidade, 99,99% dos casos de uso nunca ramificam uma promessa mais de uma vez, e a otimização desse caso comum obtém enormes melhorias no uso da memória.
Mesmo que o V8 implementasse as mesmas otimizações que o bluebird, ele ainda seria prejudicado pela especificação. O benchmark deve ser usado
new Promise
(um antipadrão no bluebird), pois não há outra maneira de criar uma promessa raiz no ES6.new Promise
é uma maneira extremamente lenta de criar uma promessa; primeiro, a função executora aloca um fechamento; depois, são passados 2 fechamentos separados como argumentos. São 3 fechamentos alocados por promessa, mas um fechamento já é um objeto mais caro do que uma promessa otimizada.O Bluebird pode usar, o
promisify
que permite muitas otimizações e é uma maneira muito mais conveniente de consumir APIs de retorno de chamada e permite a conversão de módulos inteiros em módulos baseados em promessa em uma linha (promisifyAll(require('redis'));
).fonte
new Promise
ou melhorar a instanciação para torná-la mais barata (como não criar 3 fechamentos por instância)?Promise.resolve()
para criar uma "promessa raiz"?Promise.resolve()
ou qualquer outra coisa), mas é uma implementação muito básica e sua existência não deve desencorajar o uso de ferramentas relacionadas a promessas mais sérias, como o bluebird!