Skip to content

Instantly share code, notes, and snippets.

@mschwartz mschwartz/Async.js fail

Last active Dec 30, 2015
Embed
What would you like to do?
NODE JS VERSION
===============
~/src/tmp  cat async-fail.js
var async = require('async'),
http = require ('http');
var array = [];
for (var i=0; i<250; i++) {
array[i] = Math.random();
}
http.createServer(function(req, res) {
async.parallel([
function(callback) {
async.sortBy(array, function(element, callback) {
callback(null, element);
}, callback);
},
function(callback) {
async.sortBy(array, function(element, callback) {
callback(null, element);
}, callback);
},
function(callback) {
async.sortBy(array, function(element, callback) {
callback(null, element);
}, callback);
},
function(callback) {
async.sortBy(array, function(element, callback) {
callback(null, element);
}, callback);
},
function(callback) {
async.sortBy(array, function(element, callback) {
callback(null, element);
}, callback);
},
function(callback) {
async.sortBy(array, function(element, callback) {
callback(null, element);
}, callback);
}
],
function(err, results) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('hello, world');
});
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
~/src/tmp  ab -t 30 -k -c 50 http://127.0.0.1:1337/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Finished 16388 requests
Server Software:
Server Hostname: 127.0.0.1
Server Port: 1337
Document Path: /
Document Length: 12 bytes
Concurrency Level: 50
Time taken for tests: 45.399 seconds
Complete requests: 16388
Failed requests: 0
Write errors: 0
Keep-Alive requests: 0
Total transferred: 1851844 bytes
HTML transferred: 196656 bytes
Requests per second: 360.98 [#/sec] (mean)
Time per request: 138.514 [ms] (mean)
Time per request: 2.770 [ms] (mean, across all concurrent requests)
Transfer rate: 39.83 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 2
Processing: 2 78 11.5 77 298
Waiting: 2 78 11.5 77 298
Total: 2 78 11.5 77 298
Percentage of the requests served within a certain time (ms)
50% 77
66% 77
75% 78
80% 78
90% 81
95% 82
98% 85
99% 90
100% 298 (longest request)
>>>>>>>>>>>>>>>>>>>>>>>>>>>> 360.90 requests per second. Oh my!
DECAF JS VERSION
================
~/src/tmp  cat async-compare.js
var http = require('http');
var array = [];
for (var i=0; i<250; i++) {
array[i] = Math.random();
}
http.createServer(function(req, res) {
array.sort();
array.sort();
array.sort();
array.sort();
array.sort();
array.sort();
res.writeHead(200, { 'Content-Type' : 'text/plain' });
res.end('hello, world');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
~/src/tmp  ab -t 30 -k -c 50 http://127.0.0.1:1337/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requests
Server Software:
Server Hostname: 127.0.0.1
Server Port: 1337
Document Path: /
Document Length: 12 bytes
Concurrency Level: 50
Time taken for tests: 10.729 seconds
Complete requests: 50000
Failed requests: 0
Write errors: 0
Keep-Alive requests: 50000
Total transferred: 8902314 bytes
HTML transferred: 600156 bytes
Requests per second: 4660.30 [#/sec] (mean)
Time per request: 10.729 [ms] (mean)
Time per request: 0.215 [ms] (mean, across all concurrent requests)
Transfer rate: 810.30 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 2
Processing: 2 11 14.0 8 332
Waiting: 1 11 13.9 8 332
Total: 2 11 14.0 8 333
Percentage of the requests served within a certain time (ms)
50% 8
66% 9
75% 10
80% 10
90% 15
95% 29
98% 58
99% 72
100% 333 (longest request)
4660.30 requests/second >>>>>>>>>>>>>>>>>> NODE JS GOT IT WRONG
NODE JS RUNNING THE DECAF VERSION
=================================
~/src/tmp  ab -t 30 -k -c 50 http://127.0.0.1:1337/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Finished 16392 requests
Server Software:
Server Hostname: 127.0.0.1
Server Port: 1337
Document Path: /
Document Length: 12 bytes
Concurrency Level: 50
Time taken for tests: 36.272 seconds
Complete requests: 16392
Failed requests: 0
Write errors: 0
Keep-Alive requests: 0
Total transferred: 1852296 bytes
HTML transferred: 196704 bytes
Requests per second: 451.92 [#/sec] (mean)
Time per request: 110.639 [ms] (mean)
Time per request: 2.213 [ms] (mean, across all concurrent requests)
Transfer rate: 49.87 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 8
Processing: 1 48 25.9 44 337
Waiting: 1 48 25.9 44 337
Total: 1 48 25.9 44 338
Percentage of the requests served within a certain time (ms)
50% 44
66% 45
75% 45
80% 46
90% 48
95% 50
98% 54
99% 219
100% 338 (longest request)
>>>>>>>>>>>>>>>>>>>>>>>>>> 451.92 requests/second (better than using async library)
@mschwartz

This comment has been minimized.

Copy link
Owner Author

mschwartz commented Dec 3, 2013

DecafJS running the much slower JS engine, Rhino.

Concurrency does not tell the whole story - the Decaf version serves the requests 11x faster, using 4 cores instead of NodeJS' 1 core. That's 110ms per request for NodeJS, 10ms per request for DecafJS.

array.sort() is not async! No function that doesn't have a callback argument is async in NodeJS. That means most language native methods like new Object, array.sort(), array.filter/map/reduce, JSON.stringify, and numerous others.

I run a simple 'hello, world' test using express.js and get 7000 requests/second. Awesome. I turn on gzip middleware and it drops to under 5000 requests/second. Not awesome.

The 'hello world' demo from the nodejs.org www site running in DecafJS gets about 45,000 requests/second. The same demo in NodeJS gets about 6600 requests/second.

@joeyhub

This comment has been minimized.

Copy link

joeyhub commented Jun 8, 2015

I don't think async offers real parallisation. In fact looking at the code it can't, it's all in js with no dependencies. I never used it because it looked like it didn't really offer real benefits that I needed or couldn't do in ten lines of code. Instead it looks like it just spreads out the load so that other things can execute and are not blocked for as long. The obvious problem is that the huge cost of accomplishing this defeats the point in the first place. It might even be waiting an entire tick/main loop to execute each function with parallel. I am speculating on the internals but I do know that all you are doing here is adding a huge amount of overhead with async. The cost alone of having to access each element via a callback instead of directly using what would normally likely be internal native code has to be severe. The sort is also in JS. So there's no surprise. You can see what is going to happen just by looking briefly at the code. I'm surprised you even hit 10 requests per second. I'm convinced that async.js sucks hard. But on the other hand, that's not a node.js issue. I think it would suck in decaf as well. async is more of an epic fail on the user's side.

Why didn't you run each test for both? You shouldn't really be putting a big workload on node.js request handlers either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.