http max performance experiments

167 views
Skip to first unread message

billywhizz

unread,
Apr 2, 2013, 7:57:51 AM4/2/13
to nod...@googlegroups.com
just wanted to get some feedback on some experiments i have been doing in getting maximum http performance in node.js. the code is here:


this is a c++ addon that does the absolute minimum http processing and leaves all decisions to the end user about how much support for http they want to provide. it uses ryah's http_parser to take care of http parsing and does some hacky stuff with buffers to ensure no new objects are created between requests. if you run the http-min example you can hammer it with apachebench and if you run with --trace-gc you will see that there are NO pauses for garbage collection which makes a huge performance difference. i played around with a lot of different techniques for achieving max performance and settled on the one it is currently using which is basically as follows:

- client provides an input buffer and an output buffer to the library when it is initialised. no other buffers need to be created when receiving requests or writing responses. for writes, the memcpy is taken care of in c++ land. for reads this means that once the onResponse callback has finished, the input buffer can be overwritten so it is up to the user to save the request state according to their needs.
- callbacks must be explicitly set using a setCallbacks method which binds the library to the relevant callbacks at that point. this means we don't check again if the callbacks exist which saves quite a bit of cpu time
- parsing the request requires some nasty binary parsing but this pays off big time performance-wise compared to creating lots of js objects which have to be GC'd

on my hardware i can get 67k responses a second for the absolute minimal case (just return a 200 OK keepalive request for every response). this compares to a minimal server using node.js http library giving 12k rps which is quite a boost. i have also tested it as a very basic static file server and can get the same performance as optimised nginx on my hardware. memory overhead is only 2-3 MB more than nginx too due to the fact that no objects are being created on the fly.

not sure if this approach is viable in the real world but would be interested in any feedback/ideas/gotchas that people might come up with. i would like to turn it into a low level http/tcp binding that could be useful for people who need really low level access to the protocols or might be running on a device with limited memory/cpu.

bear in mind this is very much a first pass at this so expect segfaults and all sorts of bad things to happen if anything unexpected happens. will be looking at making it more robust next.

billywhizz

unread,
Apr 2, 2013, 9:11:25 AM4/2/13
to nod...@googlegroups.com
scratch the comment about memory usage being comparable to nginx. optimised nginx uses less than 1MB RSS. no way node.js will ever come near that. however, i am getting better performance (rps) than nginx for static files on my setup at the moment but imagine nginx is probably doing more than my simple static file server which has been added to the repo.

Arnout Kazemier

unread,
Apr 2, 2013, 4:27:46 PM4/2/13
to nod...@googlegroups.com
I just want to be the first who says this:

YEAH! HTTP/TCP doesn't belong in core! Move it all to user land!

But in all seriousness, impressive stats, it just shows how much more performance there is to gain in Node.js.
--
--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en
 
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

billywhizz

unread,
Apr 2, 2013, 4:33:01 PM4/2/13
to nod...@googlegroups.com
i tend to agree. i would like core to be just a very small wrapper around libuv and everything else to be in user land. but it's too late for those kind of arguments at this stage. having said that, it is quite easy to build your own stripped down node.js with almost all of the js removed. i can post an example of this up on github if anyone is interested. on my system i can knock 2-3MB off the startup image size and have most of what i need with only 5-6 MB RSS in use.

Dan Shaw

unread,
Apr 2, 2013, 7:39:23 PM4/2/13
to nod...@googlegroups.com
I'm just going to leave this here:
https://vimeo.com/56402326

Daniel Shaw
@dshaw

billywhizz

unread,
Apr 2, 2013, 10:10:50 PM4/2/13
to nod...@googlegroups.com
thanks for the constructive feedback daniel.

Bruno Jouhier

unread,
Apr 3, 2013, 2:33:37 AM4/3/13
to nod...@googlegroups.com
Agree.

Still think that HTTP should be into core because most of us need it and we need some common ground to be able to mix and match modules. But it should be as lean and efficient as possible. Your experiment is interesting!

But why put "object mode" streams into core? That's clearly a userland thing.

Stop adding APIs! 0.6 had all we need. Just make core as fast and robust as possible.

Bruno

billywhizz

unread,
Apr 3, 2013, 12:31:00 PM4/3/13
to nod...@googlegroups.com
thanks bruno. it wasn't my intention to suggest this for core though - it is a module and a very experimental one so let's not have any more discussion about what should and shouldn't be in core on this thread please. the intention is to build a module that will be small and very fast as a starting point for folks who want to roll their own api's on top of http and sockets.
Reply all
Reply to author
Forward
0 new messages