2013-03-27 16 views
10

Więc stworzyłem ten prosty serwer testowy w Node.js
Zawsze, gdy robię bezpośrednią odpowiedź, otrzymuję żądań/sekundę (szybko!). Kiedy tylko zawijam prostą Q odroczoną wokół niego, to spada do żądań/sekundę (4 razy wolniej!). Czy ktoś może wyjaśnić tę ogromną różnicę?Jak to się dzieje, że opóźnienia Q są tak powolne w 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

Najwyraźniej obietnice Q są naprawdę powolne, po prostu czytam [to] (http://dailyjs.com/2013/03/27/node-roundup/), które wspomina o bibliotece [Vow library] (https: // github. com/dfilatov/jspromise), która najwyraźniej jest ~ 50-krotnie szybsza niż Q. – robertklep

+1

Sprawdzam również https://github.com/medikoo/deferred, i wydaje się, że nie ma też żadnego obciążenia (uzyskanie 2200 reqs/second constant). Jestem naprawdę ciekawy, dlaczego Q jest tak powolny ... –

+1

Przeglądając kod zauważam, że używa on 'process.nextTick()' dużo, co może znacznie spowolnić proces. – robertklep

Odpowiedz

5

Przyczyny jestem świadomy, to:

  1. Q wykorzystuje Object.freeze, a to spowalnia V8 o wielkości

  2. Wiele nextTick połączenia (już wspomniano w uwagach) . Nie powinno to jednak dotyczyć najnowszej wersji Node.js (v0.10), ponieważ dodatkowe nakłady są minimalne.

+2

Porada: użyj innej odroczonej biblioteki :) –

+8

Q odpowiedział na ten problem jakiś czas temu - nie używa już Object.freeze. Ponadto rozwijamy 'nextTick' tak bardzo, jak to możliwe. Wciąż jednak często używamy 'nextTick'. –

+0

@WillemMulder jakieś sugestie? – mikeybaby173

21

Edit: wydajność poprawiła się znacznie od stacktraces zostały wyłączone od Q 0.9.6. (Można je ponownie włączyć w celu debugowania za pomocą Q.longStackSupport = true;)

Oryginał: obietnice Q są powolne, ponieważ przechwytują pełny ślad stosu przy każdej obietnicy, aby pomóc w debugowaniu. To bardzo wolno. Możesz je wyłączyć za pomocą Q.longStackJumpLimit = 0; (która prawdopodobnie będzie domyślna w następnej wersji). Znaleźliśmy około 30-krotne przyspieszenie, wyłączając je. Możesz dowiedzieć się więcej tutaj https://github.com/kriskowal/q#long-stack-traces

Było też kilka performance work on the nextTick implementation, ale myślę, że powyższy jest główny powód.

+0

Dzięki, świetne informacje! :-) –

+0

Moja aplikacja dostała się 3 razy szybciej z 1 linią! * Łuki 3 razy * –

+3

W Q 0.9.6, śledzenie długiego stosu jest domyślnie wyłączone. –

Powiązane problemy