简体   繁体   中英

Node.js stream write in loop

I was trying to benchmark some node.js native functionalities lately and found out some creepy results I cannot understand. Here's a simple code that I benchmarked and benchmark results:

http://pastebin.com/0eeBGSV9

You can see that it did healthy 8553 requests per second on 100k requests with 200 concurrency. I was then instructed by a friend, that I shouldn't be using async in this case, as this loop isn't big enough to obstruct event loop of node, so I refactored code to use for loop and it increased the benchmark result even higher:

http://pastebin.com/0jgRPNEC

Here we have 9174 requests per second. Neat. (for loop version was consistently faster than async version even when I changed the amount of iterations to 10k, curiously enough).

But then my friend wandered if this result could be pushed even further by use of streaming instead of dumping all data after loop has finished. Once again, I refactored code to use res.write to handle data output:

http://pastebin.com/wM0x5nh9

aaaaand we have 2860 requests per second.

Node version is 0.10.25 on ubuntu with default settings from apt installation.

I also tested the same code against JXCore and HHVM (using async.js version of node code) in the beginning with results here: http://pastebin.com/6tuYGhYG and got a curious result of node cluster being faster than latest jxcore 2.3.2.

Any critique would be greatly appreciated.

EDIT: @Mscdex, I was curious if calling res.write() might have been the issue, so I changed the way I pushed out data to a new stream made for consumption by res. I believed, naively, that maybe this way node will somehow optimize output buffering and stream data in an effective way. While this solution worked too, it was even slower than before:

http://pastebin.com/erF6YKS5

My guess would be the overhead involved with having many separate write() syscalls.

In node v0.12+, "corking" functionality has been added so that you can do res.write() as much as you want, but you can cork and uncork the stream so that all of those writes only result in a single write() syscall. This is essentially what you're doing now with the concatenating of the output, except the corking will do that for you. In some places in node core, this corking functionality may also be used automatically behind the scenes so that you don't have to explicitly cork/uncork to get good performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM