Pull to refresh

Comments 19

Нет. Но вы можете сравнить и поделиться результатами.
Расскажите где были самые узкие места? :-)
Не разработчик, но расскажу:
Самая дорогая операция — nextTick, но тут все Promise/A+ равны. Поэтому даже самый плохой Promise/A будет быстрее любого Promise/A+ в синтетических тестах
Q — адов функциональный кошмар, генерация функций вместо использования прототипов — долго, не оптимально, затратно по памяти
Vow — чистые прототипы, нет генераций функций. Поэтому предельно дешево, JIT-friendly. Но нужно немного допилить, чтобы было совсем хорошо.
а почему вы считайте, что такая архитектура javascript'a (функция, в ней куча прототипов, а потом инициализация) JIT-friendly? Можно какую-то инфу по этому поводу?
Как быстро истекает время на редактирование), добавлю:
Не в сравнении, конечно, с генерацией функций выше (это понятно, что быстрее будет), а с более классическим подходом, когда функции это методы в объекте, а инициализация просто собирает их по необходимости.
Во многих виртуальных машинах JavaScript к функции при ее инициализации добавляется специальный объект Scope, который описывает область видимости функции и чаще всего он инициализируется сразу же — в него попадают ссылки на все переменные контекстов до которых может достучаться функция. Если переменных много и контекст многоуровневый и функции генерируются очень часто (типичный функциональный подход), то это дорого. Полюс ко всему JIT компилятору нужно каждый раз оптимизировать каждую функцию.

Методы прототипа инициализируются только один раз и делегируют свое использование инстансу.
Вот бы технических деталей, а то эти сухие тесты.
А результат для Q в таблице приведен с опцией «Q.longStackJumpLimit = 0» или без?
Насколько я помню, там в тесте Q была версии 0.8, в ней вроде еще не было этой опции.
Сейчас померял с Q 0.9 — там отключение этой опции дает существенный буст, она становится даже чуть быстрее When (примерно на 10-15%).
А deferred? Не паранои ради, а для порядка.

Еще есть один важный хэлпер — Q.nfbind и Q.nfapply, Q.nfcall с ним. С ним можно просто сделать вот:
var readFile = Q.nfbind(fs.readFile);

Понятно, что есть vow-fs, но nfbind нужен не только для fs.

Еще есть достаточно частый кейс, когда разработчик ожадает, что функции resolve и reject забиндены к контексту при рождении. И можно делать вот так:
var timeout = function (ms) {
    var dfd = $.Deferred();
    
    setTimeout(dfd.resolve, ms);
    
    return dfd.promise();
};

// VS

var timeout = function (ms) {
    var promise = Vow.promise();
    
    // .bind :(
    setTimeout(promise.fulfill.bind(promise), ms);
    
    return promise;
};

Понятно, что vow выигрывает на экономии в бинде, но это уродует код.
согласен с Димой, что эти функции правильнее вынести в дополнительный модуль, а не в ядро
dfilatov, замерь еще использование памяти и GC на каком-нибудь долгоиграющем тесте.
Можешь посоветовать какую-нибудь тулзу для автоматизации этого?
mean time ops/sec
Q 98.002ms 10
When 16.895ms 59
Vow 12.302ms 81
fibers/promise 12.738ms 79

и это в свете того, что в последнем случае есть классная функция wait, приостанавливающая текущее волокно в ожидании ответа

benchmarks/comparison.js | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)

diff --git a/benchmarks/comparison.js b/benchmarks/comparison.js
index 8520d17..7bcf306 100644
— a/benchmarks/comparison.js
+++ b/benchmarks/comparison.js
@@ -6,6 +6,34 @@ var cliff = require('cliff'),
Q = require('q'),
When = require('when'),
tests = {
+ 'fibers/promise': function(deferred){
+ var Fiber = require('fibers');
+ var Future= require('fibers/future')
+
+ var toResolve = [],
+ topPromises = [];
+
+ Object.keys(data).forEach(function(key) {
+ var promises= data[key].map(function(val) {
+ var promise = new Future();
+ toResolve.push({ promise: promise, val: val });
+ return promise;
+ })
+ topPromises.push(promises);
+ });
+
+ Fiber( function(){
+ var result= topPromises.map(function(promises){
+ return Future.wait( promises)
+ })
+ deferred.resolve()
+ }).run()
+
+ toResolve.forEach(function(obj) {
+ obj.promise.return(obj.val);
+ });
+ },
+
'Q': function(deferred) {
var toResolve = [],
topPromises = [];
Библиотека изменила синтаксис, стоит сделать апдейт поста.
Sign up to leave a comment.

Articles