2013-03-27 3 views
10

Donc, j'ai créé ce serveur de test simple dans Node.js
Chaque fois que je fais une réponse directe, je reçois demandes/seconde (rapide!). Lorsque je n'emballe qu'un Q Q différé autour de lui, il passe à requêtes/seconde (4 fois plus lent!). Quelqu'un peut-il expliquer cette énorme différence?Pourquoi les Q différés sont-ils si lents sur Node.js?

// 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); 
+0

Apparemment, les promesses Q sont vraiment lentes, je viens de lire [this] (http://dailyjs.com/2013/03/27/node-roundup/) qui mentionne la [bibliothèque de voeux] (https: // github. com/dfilatov/jspromise) qui est apparemment ~ 50 fois plus rapide que Q. – robertklep

+1

Je vérifie https://github.com/medikoo/deferred pour le moment aussi, et il semble ne pas avoir de frais généraux non plus (se rendre à 2200 reqs/seconde régulièrement). Je suis vraiment curieux de savoir pourquoi Q est si lent ... –

+1

En parcourant le code, je remarque qu'il utilise beaucoup 'process.nextTick()', ce qui pourrait ralentir considérablement les choses. – robertklep

Répondre

5

Les raisons pour lesquelles je suis au courant, sont les suivants:

  1. Q utilise Object.freeze, et que V8 par des grandeurs ralentit

  2. Beaucoup nextTick appels (déjà mentionnés dans les commentaires) . Cela ne devrait cependant pas être le cas avec la dernière version de Node.js (v0.10), car la surcharge de nextTick est minime.

+2

Conseil: utiliser une autre lib différée :) –

+8

Q a répondu à ce problème il y a quelque temps - il n'utilise plus Object.freeze. Nous déroulons aussi 'nextTick' autant que possible. Nous utilisons toujours 'nextTick' fréquemment. –

+0

@WillemMulder des suggestions? – mikeybaby173

21

Edit: Performance est grandement améliorée depuis stacktraces ont été désactivés depuis Q 0.9.6. (Ils peuvent être réactivés pour le débogage avec Q.longStackSupport = true;)

Original: les promesses Q sont lentes car elles capturent une trace de pile complète sur chaque promesse d'aide au débogage. C'est très lent. Vous pouvez les désactiver avec Q.longStackJumpLimit = 0; (ce qui est susceptible d'être la valeur par défaut dans la prochaine version). Nous avons trouvé une accélération d'environ 30x en les éteignant. Vous pouvez en savoir plus ici https://github.com/kriskowal/q#long-stack-traces

Il y a aussi eu quelques performance work on the nextTick implementation, mais je pense que ce qui précède est la raison principale.

+0

Merci, bonne information! :-) –

+0

Mon application vient d'être 3 fois plus rapide avec 1 ligne! * arcs 3 fois * –

+3

Dans Q 0.9.6, les traces de longue pile sont maintenant désactivées par défaut. –

Questions connexes