Почему 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, но я думаю, что это главная причина.