Почему Q откладывается так медленно на Node.js?
Итак, я создал этот простой тестовый сервер в Node.js
Всякий раз, когда я делаю прямой ответ, я получаю 2200 запросов/секунду (быстро!).
Когда я закрываю только простую Q, отложенную вокруг нее, она падает до 580 запросов/секунд ( в 4 раза медленнее!). Может ли кто-нибудь объяснить эту огромную разницу?
// Requires
var server = require('http');
var q = require('q');
// Start server
var http = require('http');
http.createServer(function(request, response) {
// Comment out either of two below sections
// Without deferred
// 2200 reqs/second
response.writeHead(200, {"Content-Type": "text/html"});
response.write("test");
response.end();
// Q deferred
// 580 reqs/second
var deferred = q.defer();
deferred.promise.then(function() {
response.writeHead(200, {"Content-Type": "text/html"});
response.write("test");
response.end();
});
deferred.resolve();
}).listen(1234);
Ответы
Ответ 1
Причины, о которых я знаю, следующие:
-
Q использует Object.freeze и замедляет V8 по величинам
-
Многие вызовы nextTick (уже упомянутые в комментариях). Это, однако, не должно быть так много в случае с последней версией Node.js(v0.10), так как накладные расходы NextTick минимальны.
Ответ 2
Изменить: Производительность значительно улучшилась, так как stacktraces были отключены с Q 0.9.6. (Они могут быть повторно включены для отладки с помощью Q.longStackSupport = true;
)
Оригинал: Q promises являются медленными, потому что они фиксируют полную трассировку стека на каждое обещание, чтобы помочь с отладкой. Это очень медленно. Вы можете отключить их с помощью Q.longStackJumpLimit = 0;
(который, вероятно, будет использоваться по умолчанию в следующей версии). Мы обнаружили примерно 30-кратное ускорение, отключив их. Вы можете узнать больше здесь https://github.com/kriskowal/q#long-stack-traces
Также была некоторая работа над реализацией nextTick, но я думаю, что это главная причина.