W tym teście pakiet zajmuje 4 razy więcej czasu, niż spełnienie obietnic ES6 w porównaniu z obietnicami Bluebird, i zużywa 3,6 razy więcej pamięci.
W jaki sposób biblioteka JavaScript może być znacznie szybsza i lżejsza niż natywna implementacja v8 napisana w C? Obietnice Bluebird mają dokładnie taki sam interfejs API jak natywne obietnice ES6 (plus kilka dodatkowych metod narzędziowych).
Czy natywna implementacja jest po prostu źle napisana, czy też brakuje mi jakiegoś innego aspektu?
javascript
performance
io.js
kalus
źródło
źródło
new
operatora, ponieważ PromiseMeSpeedJS nie korzystanew
.Odpowiedzi:
Autor Bluebird tutaj.
V8 obiecuje, że implementacja jest napisana w JavaScript, a nie C. Cały JavaScript (w tym własny V8) jest kompilowany do kodu natywnego. Dodatkowo JavaScript napisany przez użytkownika jest zoptymalizowany, jeśli to możliwe (i warto), przed skompilowaniem do kodu natywnego. Implementacja obietnic jest czymś, co nie przyniosłoby wiele korzyści lub wcale nie byłoby napisane w C, w rzeczywistości spowolniłoby to, ponieważ wszystko, co robisz, to manipulowanie obiektami JavaScript i komunikacją.
Implementacja V8 po prostu nie jest tak zoptymalizowana jak bluebird, na przykład alokuje tablice dla programów obsługi obietnic . Zajmuje to dużo pamięci, gdy każda obietnica musi również przydzielić kilka tablic (test porównawczy tworzy ogólnie 80 tys. Obietnic, więc przydzielono 160 tys. Nieużywanych tablic). W rzeczywistości 99,99% przypadków użycia nigdy nie rozgałęzia obietnicy więcej niż jeden raz, więc optymalizacja dla tego typowego przypadku zyskuje ogromne ulepszenia wykorzystania pamięci.
Nawet jeśli V8 zaimplementowałoby te same optymalizacje, co Bluebird, nadal byłoby to utrudnione przez specyfikację. Benchmark musi zostać wykorzystany
new Promise
(anty-wzór w bluebird), ponieważ nie ma innego sposobu na stworzenie obietnicy root w ES6.new Promise
to niezwykle powolny sposób tworzenia obietnicy, najpierw funkcja executora przydziela zamknięcie, po drugie przekazuje 2 oddzielne zamknięcia jako argumenty. To 3 zamknięcia przydzielone na obietnicę, ale zamknięcie jest już droższym przedmiotem niż zoptymalizowana obietnica.Można użyć Bluebird,
promisify
który umożliwia wiele optymalizacji i jest znacznie wygodniejszym sposobem korzystania z interfejsów API wywołania zwrotnego oraz umożliwia konwersję całych modułów na moduły oparte na obietnicach w jednym wierszu (promisifyAll(require('redis'));
).źródło
new Promise
lub poprawy instancji, aby uczynić ją tańszą (np. Nie tworząc 3 zamknięć na instancję)?Promise.resolve()
„obietnicy root”?Promise.resolve()
lub cokolwiek), ale jest to bardzo podstawowa implementacja, a jej istnienie nie powinno zniechęcać do korzystania z poważniejszych narzędzi związanych z obietnicami, takich jak bluebird!