Benchmarks: Node.js vs Go (vs PHP)

With talk lately about Go, the Google sponsored programming language), and what performance benefits it holds, I thought I'd go and do a quick benchmark of Go, Node.js, and PHP.

Update: Node.js vs. Go 1.1

Disclaimer: Make the smartest decision possible when choosing a language. Benchmarks give you a rough idea of language speed, but do not provide insights into real world usability, productivity, or what is best for you or your company. In short, take these numbers wisely.

The test

Here's the first test. A rusty old Bubble sort. I use this because it gives a good idea of how long computations and comparison operations take for the specific language to perform. Here's the code I used:

PHP

<?php
$starttime = microtime(true);

$array = array(3,4,1,3,5,1,92,2,4124,424,52,12);

for ($c=0;$c<100000;$c++) {

for ($i=0;$i<count($array);$i++) {
    for ($y=0;$y<count($array)-1;$y++) {
        if ($array[$y+1] < $array[$y]) {
            $t = $array[$y];
            $array[$y] = $array[$y+1];
            $array[$y+1] = $t;
        }
    }
}

}
print_r($array);
echo microtime(true) - $starttime;

Node.js

var starttime = new Date().getTime();

var array = [3,4,1,3,5,1,92,2,4124,424,52,12];

for (var c = 0; c < 100000; c++) {
    for (var i = 0; i < array.length; i++) {
        for (var y = 0; y < array.length - 1; y++) {
            if (array[y+1] < array[y]) {
                var t = array[y];
                array[y] = array[y + 1];
                array[y + 1] = t;
            }
        }
    }
}
console.log(array);
console.log(new Date().getTime() - starttime);

Go

package main

import "fmt"
import "time"

func main() {

timestart := time.Now();

array := [...]int16{3,4,1,3,5,1,92,2,4124,424,52,12}

for c := 0; c < 100000; c++ {

for i := 0; i < len(array); i++ {
    for y := 0; y < len(array) - 1; y++ {
        if array[y+1] < array[y] {
            t := array[y]
            array[y] = array[y+1]
            array[y+1] = t
        }
    }
}

}

fmt.Print(array);
fmt.Print("\n");

timeend := time.Now();

fmt.Print(timeend.Sub(timestart));

}

Without further ado, here are the results:

Holy slow is slow, PHP. That's a full three seconds, verses the less than 100ms boasted by Node.js and Go. Let's remove the outlier:

PHP completed the operations in 3.835 seconds. Node.js completed them in 71 milliseconds, whereas Go completed them in 38ms. Not bad, those latter two.

Conclusion

As a language, Go does seem faster than Node.js by a significant margin. This being said, the two are both eons ahead of PHP in speed, which we all already knew. The performance gains from both of them, compared to PHP, shows they are both relatively fast when compared to a very popular language for web development.

Test 2: HTTP

Now, since we're talking in the context of the web, I thought I'd compare Node.js and Go's HTTP capabilities.

Go

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "You requested %s", r.URL.Path)
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

Node.js

var http = require("http");

http.createServer(function(request,response) {
    response.writeHeader(200);

    response.write("You requested " + request.url);

    response.end();
}).listen(8080);

Without further ado, the ApacheBench results:

Again, lower is better. In this case, Node barely outperformed Go in handling static HTTP requests, but not by much of a margin (~1ms).

Now, if we throw the bubble sort code into the request handler function, we get obviously this:

Here, the computation efficiency of Go wins over Node.js. But computing 100,000 bubble sort operations is probably not on the scale of data processing is required per request to your users, so we'll drop the loop and do one bubble sort per request:

Now that's interesting. Here, it appears that the HTTP transport of Node.js is more efficient than Go's, despite the lower computation speed. If we increase the concurrency, the gap between the two grows:

Conclusion

My only strong conclusion from this is, if your goal is to optimize past the speeds of PHP or other similar languages, Go and Node.js are good alternatives. Which should you use? This information can't tell you that. It would appear, and make sense, that Go handles data processing more efficiently than Node. But at the same time, it does appear that Node may scale more efficiently, at least in the almost pure HTTP side of things. In a real world scenario, the type of operations your application does will be critical in determining this. One thing I didn't benchmark, and I wish I had time to, is database driver speeds, but that's another topic for another time. In the end, though, I'd say language choice is truly up to preference and suitability for your project. Go may be somewhat faster in a few cases, and Node in others, but both Node.js and Go are eons faster than PHP. It truly depends on your team's experience and what type of operations are at hand.

Any questions, suggestions, or better points are welcomed (and encouraged)

Update: Node.js vs. Go 1.1