Websocket Shootout: Clojure, C++, Elixir, Go, Node.js, and Ruby
hashrocket.com
hashrocket.com
- Phoenix Channels is a higher-level abstraction over raw WS. We spawn isolated, concurrent "channels" on the underlying WebSocket connection. We monitor these channels so that clients can detect errors and recover automatically without dropping the entire connection. This contributes to overhead in both memory and throughput, which should be highlighted with how Phoenix faired in the runs.
- Phoenix channels runs on a distributed pubsub system. None of the other contestants had a distribution story, so their broadcasts are only node-local implementations, where ours is distributed out of the box
Phoenix faired quite well in these runs, considering we are comparing a robust feature set vs raw ws/pubsub implementations.
My takeaways from this article were:
1) Phoenix and Rails are clear winners on API.
2) Rails performance is unacceptable, which makes its nice API irrelevant.
3) All others are good enough that if I wanted to choose them for other reasons, this article wouldn't stop me.
Of note is that of these, I think only the elixir and ruby (?) solutions are distributed. Additionally, Phoenix channels are doing a lot of work that the other solutions aren't.
The library and the the lack of clustering (so you can compare apples to apples) are the main two.
Honestly? Running at 39% of the connections on one core is pretty impressive. Especially with its low memory footprint.
Though clustering would have meant the need for another control channel.. that said, I'd be surprised if Redis + Node(clustered) didn't perform in with the leaders of the pack.
With clustering -as that has overhead - I'd expect it to perform at least as fast as Elixir or Go.
Of course you can also just use multiple cheaper single core servers too! I've seen that used a lot for certain applications - kinda overkill here tho.
I happened to come across this in /r/haskell today. The results are very impressive.
It would be awesome to see implementations in python, c# and java. There are a number of ways to do each, I assume.
Both high speed and simple to develop :
http://docs.spring.io/spring/docs/current/spring-framework-r...
In the end, if you're within 10% is probably moot, and at 39% on a single instance for node, that's very impressive and once you add multiple system, multiple instances per system aren't any harder and node would probably make up most of the difference.
Seriously though, Node is written in C++ and is a single threaded interpreted / Jitted / Garbage Collected Virtual Machine which has to jump through trampolines and layers of abstraction to call system services.
While it might be very efficient at what it does, it isn't as close to the machine as a native C++ application.
One asynchronous WebSocket server written in C++ can run rings around one Node WebSocket server.
If the premise is that to mitigate this we can set up an entire cluster of node servers that will beat the C++ server, it follows that we can set up an entire cluster of C++ servers that would be even faster.
C++ is faster in every regard. There is no "usually", about it.
If we are talking about some metric like programmer productivity, sure sometimes it takes more effort to write code in C++ to achieve what may take a single line in Node.
Otherwise, totally agreed.
Right tool for the right job is fine
The trick is to minimize aggregate kWh of energy use per unit task. Sometimes that means ordering a take out, and occasionally baking a pie.
A lot of the time I'm in the position of buildng upstream tools and platforms for people downstream, so whatever I do has a direct impact on their performance. The way I look at it is it is my duty to make them look good.
I do take that a little far though on occasion. Shipping is a feature too of course. Heh.
Both also make it pretty natural to async everything. If Node beat either in a distributed benchmark it would be a shock to all involved.
Yep