user774742
user774742

Reputation:

Is this a good way to demonstrate Nodejs (expressjs) advantage over Rails/Django/etc?

UPDATE

This was not supposed to be a benchmark, or a node vs ruby thing (I should left that more clear in the question, sorry). The point was to compare and demonstrate the diference between blocking and non blocking and how easy it is to write non blocking. I could compare using EventMachine for exemple, but node has this builtin, so it was the obvious choice.


I'm trying to demonstrate to some friends the advantage of nodejs (and it's frameworks) over other technologies, some way that is very simple to understand mainly the non blocking IO thing.

So I tried creating a (very little) Expressjs app and a Rails one that would do a HTTP request on google and count the resulting html length.

As expected (on my computer) Expressjs was 10 times faster than Rails through ab (see below). My questioon is if that is a "valid" way to demonstrate the main advantage that nodejs provides over other technologies. (or there is some kind of caching going on in Expressjs/Connect?)

Here is the code I used.

Expressjs

exports.index = function(req, res) {
    var http = require('http')
    var options = { host: 'www.google.com', port: 80, method: 'GET' }
    var html = ''
    var googleReq = http.request(options, function(googleRes) {
        googleRes.on('data', function(chunk) {
            html += chunk
        })
        googleRes.on('end', function() {
            res.render('index', { title: 'Express', html: html })
        })
    });
    googleReq.end();
};

Rails

require 'net/http'

class WelcomeController < ApplicationController
  def index
    @html = Net::HTTP.get(URI("http://www.google.com"))
    render layout: false
  end
end

This is the AB benchmark results

Expressjs

Server Software:        
Server Hostname:        localhost
Server Port:            3000

Document Path:          /
Document Length:        244 bytes

Concurrency Level:      20
Time taken for tests:   1.718 seconds
Complete requests:      50
Failed requests:        0
Write errors:           0
Total transferred:      25992 bytes
HTML transferred:       12200 bytes
Requests per second:    29.10 [#/sec] (mean)
Time per request:       687.315 [ms] (mean)
Time per request:       34.366 [ms] (mean, across all concurrent requests)
Transfer rate:          14.77 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       0
Processing:   319  581 110.6    598     799
Waiting:      319  581 110.6    598     799
Total:        319  581 110.6    598     799

Percentage of the requests served within a certain time (ms)
  50%    598
  66%    608
  75%    622
  80%    625
  90%    762
  95%    778
  98%    799
  99%    799
 100%    799 (longest request)

Rails

Server Software:        WEBrick/1.3.1
Server Hostname:        localhost
Server Port:            3001

Document Path:          /
Document Length:        65 bytes

Concurrency Level:      20
Time taken for tests:   17.615 seconds
Complete requests:      50
Failed requests:        0
Write errors:           0
Total transferred:      21850 bytes
HTML transferred:       3250 bytes
Requests per second:    2.84 [#/sec] (mean)
Time per request:       7046.166 [ms] (mean)
Time per request:       352.308 [ms] (mean, across all concurrent requests)
Transfer rate:          1.21 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0  180 387.8      0     999
Processing:   344 5161 2055.9   6380    7983
Waiting:      344 5160 2056.0   6380    7982
Total:        345 5341 2069.2   6386    7983

Percentage of the requests served within a certain time (ms)
  50%   6386
  66%   6399
  75%   6402
  80%   6408
  90%   7710
  95%   7766
  98%   7983
  99%   7983
 100%   7983 (longest request)

Upvotes: 3

Views: 787

Answers (2)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230336

To complement Sean's answer:

Benchmarks are useless. They show what you want to see. They don't show the real picture. If all your app does is proxy requests to google, then an evented server is a good choice indeed (node.js or EventMachine-based server). But often you want to do something more than that. And this is where Rails is better. Gems for every possible need, familiar sequential code (as opposed to callback spaghetti), rich tooling, I can go on.

When choosing one technology over another, assess all aspects, not just how fast it can proxy requests (unless, again, you're building a proxy server).

Upvotes: 5

Sean Hill
Sean Hill

Reputation: 15056

You're using Webrick to do the test. Off the bat the results are invalid because Webrick can only process on request at a time. You should use something like thin, which is built on top of eventmachine, which can process multiple requests at a time. Your time per request across all concurrent requests, transfer rate and connection times will improve dramatically making that change.

You should also keep in mind that request time is going to be different between each run because of network latency to Google. You should look at the numbers several times to get an average that you can compare.

In the end, you're probably not going to see a huge difference between Node and Rails in the benchmarks.

Upvotes: 1

Related Questions