Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How come Q deferreds are so slow on Node.js?

So I created this simple test server in Node.js
Whenever I do a direct response, I get 2200 requests/second (fast!). When I only wrap a simple Q deferred around it, it drops to 580 requests/second (4 times slower!). Can anybody explain that huge difference?

// 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);
like image 831
Willem Mulder Avatar asked Mar 27 '13 20:03

Willem Mulder


People also ask

Why is my node so slow?

Node. js programs can be slow due to a CPU/IO-bound operation, such as a database query or slow API call. For most Node. js applications, data fetching is done via an API request and a response is returned.

How does node js have high IO throughput?

Node. js is asynchronous and single-threaded. This means that all I/O operations don't block any other operations. It also means that you can send emails, read files, query the database, etc.


2 Answers

Edit: Performance has improved greatly since stacktraces have been turned off since Q 0.9.6. (They can be re-enabled for debugging with Q.longStackSupport = true;)

Original: Q promises are slow because they capture a full stack trace on every promise to help with debugging. This is very slow. You can turn them off with Q.longStackJumpLimit = 0; (which is likely to be the default in the next version). We found a roughly 30x speedup by turning them off. You can find out more here https://github.com/kriskowal/q#long-stack-traces

There's also been some performance work on the nextTick implementation, but I think the above is the main reason.

like image 164
Stuart K Avatar answered Sep 21 '22 03:09

Stuart K


The reasons I'm aware of, are:

  1. Q uses Object.freeze, and that slows V8 by magnitudes

  2. Many nextTick calls (already mentioned in comments). This however shouldn't be that much of the case with latest Node.js version (v0.10), as there nextTick overhead is minimal.

like image 24
Mariusz Nowak Avatar answered Sep 23 '22 03:09

Mariusz Nowak