Perché gli ES6 nativi promettono più lento e più memoria di bluebird?

185

In questo benchmark , la suite impiega 4 volte di più per completare le promesse ES6 rispetto alle promesse di Bluebird e utilizza 3,6 volte la quantità di memoria.

Come può una libreria JavaScript essere molto più veloce e leggera dell'implementazione nativa di v8 scritta in C? Le promesse di Bluebird hanno esattamente la stessa API delle promesse native di ES6 (più una serie di metodi extra di utilità).

L'implementazione nativa è appena stata scritta male, o c'è qualche altro aspetto che mi manca?

    
posta callum 10.04.2015 - 22:12
fonte

1 risposta

258

Autore Bluebird qui.

V8 promette che l'implementazione è scritta in JavaScript non C. Tutto JavaScript (incluso quello del V8) è compilato in codice nativo. Inoltre, il JavaScript scritto dall'utente viene ottimizzato, se possibile (e ne vale la pena), prima di essere compilato in codice nativo. L'implementazione di promesse è qualcosa che non gioverà molto o affatto di essere scritta in C, anzi, lo renderebbe più lento perché tutto ciò che stai facendo è manipolare oggetti e comunicazioni JavaScript.

L'implementazione V8 semplicemente non è ottimizzata come bluebird, ma per istanze assegna gli array ai gestori di promesse . Ciò richiede molta memoria ogni volta che ogni promessa deve allocare un paio di array (il benchmark crea promesse complessive di 80k in modo che siano allocati 160.000 array inutilizzati). In realtà il 99,99% dei casi d'uso non promuove più di una volta in modo che l'ottimizzazione per questo caso comune ottenga enormi miglioramenti nell'utilizzo della memoria.

Anche se V8 implementasse le stesse ottimizzazioni di bluebird, sarebbe comunque ostacolato dalle specifiche. Il benchmark deve usare new Promise (un anti-pattern in bluebird) in quanto non esiste un altro modo per creare una promessa di root in ES6. new Promise è un modo estremamente lento di creare una promessa, prima la funzione executor alloca una chiusura, in secondo luogo si passano 2 chiusure separate come argomenti. Sono 3 le chiusure assegnate per promessa, ma una chiusura è già un oggetto più costoso di una promessa ottimizzata.

Bluebird può utilizzare promisify che abilita molte ottimizzazioni ed è un modo molto più conveniente di utilizzare le API callback e consente la conversione di interi moduli in moduli basati su promesse in una riga ( promisifyAll(require('redis')); ).

    
risposta data 14.04.2015 - 09:22
fonte

Leggi altre domande sui tag