Hacker News new | ask | show | jobs
by jchw 605 days ago
Haha, I was flabbergasted to see the results of the subprocess approach, incredible. I'm guessing the memory usage being lower for that approach (versus later ones) is because a lot of the heavy lifting is being done in the subprocess which then gets entirely freed once the request is over. Neat.

I have a couple of things I'm wondering about though:

- Node.js is pretty good at IO-bound workloads, but I wonder if this holds up as well when comparing e.g. Go or PHP. I have run into embarrassing situations where my RiiR adventure ended with less performance against even PHP, which makes some sense: PHP has tons of relatively fast C modules for doing some heavy lifting like image processing, so it's not quite so clear-cut.

- The "caveman" approach is a nice one just to show off that it still works, but it obviously has a lot of overhead just because of all of the forking and whatnot. You can do a lot better by not spawning a new process each time. Even a rudimentary approach like having requests and responses stream synchronously and spawning N workers would probably work pretty well. For computationally expensive stuff, this might be a worthwhile approach because it is so relatively simple compared to approaches that reach for native code binding.

4 comments

The native code binding was impressively simple!

7 lines of rust, 1 small JS change. It looks like napi-rs supports Buffer so that JS change could be easily eliminated too.

I've used napi-rs a bit ago, it's pretty awesome. That said though, the main issue is that the Rust bindings story is not always that nice. It really depends. Internally, Node modules have quite a lot of complexity, and when you try to do more interesting things you could wind up facing some of the complexity of how it is implemented.
Depends on the situation, but posix_spawn is really fast on Linux (much faster than the traditional fork/exec), and independent processes provide fault isolation boundaries.
> You can do a lot better by not spawning a new process each time. Even a rudimentary approach like having requests and responses stream synchronously and spawning N workers would probably work pretty well

And with just a tiny bit of extra work you can give the worker an http interface.... Wait a minute.,.

Caveman approach has several nice features - I think I'd be tempted even if it didn't have better performance.