IT IS HERE! Get Smashing Node.JS on Amazon Kindle today!
Show Posts
← Back to homepage

Daniel Kang recently made public a partial implementation of the Node.JS API in C++11 (also known as C++0x) named node.native.

#include <iostream>
#include "http.h"
using namespace native::http;

int main()
{
    http server;
    if(server.listen("0.0.0.0", 8080, [](request& req, response& res){
        res.set_status(200);
        res.set_header("Content-Type", "text/plain");
        res.end("C++ FTW\n");
    })) std::cout << "Server running at http://0.0.0.0:8080/" << std::endl;

    return native::run();
}

Why is a C++ port of Node.JS exciting?

  1. The language has seen the addition of a large number of features designed to improve the usability of the language. In particular, anonymous functions are part of node.native’s “Hello World” (seen above) and used throughout the codebase.
  2. The interoperability with the existing C/C++ library ecosystem and tooling, combined with enhanced usability make C++11 very appealing. Projects like node.native prove the additions can translate into real-world APIs that could not be as straightforward otherwise.
  3. Successful companies like OKCupid have written entire codebases for networked applications (Node.JS’s niche) in C++. According to its co-founder, the main reason for this decision was performance, which we’re setting out to briefly look at for C++0x in this article.

The stage

The benchmarks were run on a Macbook Air laptop running OS X 10.7.2, with a 1.8 GHZ Intel Core i7 processor and 4 GB 1333 MHZ DDR3 memory.

  • JavaScript: Node v0.6.10
  • LuaJIT: Luvit v0.1.5 – LuaJIT v2.0.0-beta9
  • C++: node.native-117ed2 – GCC v4.6.2

The code that powers each server is found in this gist. All servers should behave in almost the exact same way. They all produce a “Hello World” 200 text/plain response.

The tests are run with “ab” with the following settings:

 ∞ ~ ab -c 10 -n 1000 http://127.0.0.1:8080/

In order to compile node.native on OS X I installed GCC 4.6.2 separately from XCode’s, and I removed the linking to librt unavailable on the mac.

The results

The clear winner of the simple benchmark is node.native, followed by Luvit and Node.JS, being almost 40% and 80% faster respectively.

Keep in mind this should be used as a vague reference and ongoing experiment, rather than a benchmark study to make actual decisions from.

It’s still interesting to see the application of libuv and the Node.JS model to other languages and the performance differences of the implementations, none of which in my opinion significant enough so far to dethrone JavaScript as the one language to rule them all.

Update: following node.native’s author advice, compiling node.native with the right optimization flags has yielded a drastic performance increase! The benchmark results have been updated to reflect this.

8 Comments

Anand George said

Started the day trying out node.native followed by luvit. End of day have a benchmark. Wow… quite a day. Thanks

kelvinc said

I’m unsure why that would be a relevant benchmark. It doesn’t seem to reflect a real use-case at all.

SaltwaterC said

I hope you do realize that a Hello World benchmark is mostly pointless for getting the complete picture. Also, 10 concurrent requests with a total of 1000 requests? Please. Last time when I did a “Hello World” benchmark against node.js, I had like around 8000 req/s on -c 1000 -n 100000. That actually took more than a second to finish.

Guillermo Rauch said

@kelvinc, @SaltwaterC

Please re-read the last few paragraphs where I mention precisely this is not a benchmark to get the “complete picture”.

Tim Caswell said

Thanks for writing this up. I’m not sure what it shows except that libuv is fast everywhere and luajit is a really low overhead scripting engine. It does make me smile to see Luvit come out ahead of node.native.

Of course benchmarks like this don’t mean much, but there is something real there giving the different results.

A more interesting benchmark would be memory usage of the various servers. The people I know using luvit in production are doing it because it uses 20x less ram than node for a simple process, not because it’s faster. Let’s face it, they are all really fast!

pnmahoney said

Hey- great writeup. I was just wondering one thing – as the saying goes, “genuine curiosity” – why is javascript the one language to rule them all? (Or at least as far as reactor pattern http stuff, as far as this writeup is concerned…) I would probably guess the widespread availability of libraries and interoperability with js frontend libraries? Or just the ease of dropping in js modules which each are written async’ly – which would be harder to make interoperable with c++ libraries that would have to call each other?

Again – genuine curiosity. The speed difference, to me, is not terribly consequential. You’ll find me coding in node/express for these things right now, but I’m just wondering exactly why I, uh, (wouldn’t not) stay there.

Jeff S. said

“none of which in my opinion significant enough so far to dethrone JavaScript as the one language to rule them all”

But really, there’s no real world advantage to limiting yourself to a single language, especially not when it’s one of the worst languages in existence.

People try to say JavaScript is “Scheme with C syntax”. Well, almost all dynamic languages borrow heavily from Scheme. You can’t make JavaShit look “good by association” with such meaningless comments.

JavaShit sucks, one-language-to-rule-them-all is just hipster nonsense, and Node.js is a horrible pile of cancer.

Your thoughts?

About Guillermo Rauch:

CTO and co-founder of LearnBoost / Cloudup (acquired by Automattic in 2013). Argentine living in SF.