Node.js フロー制御モジュール速度比較

Node.js のフロー制御モジュールといえば async と step が有名ですね。
私は node-block という自作モジュールを使っているのですが、速度的なパフォーマンスが気になったのでベンチマークをとってみました。

実行環境 (Mac OS X 10.7.4 Node.js v0.9.0)
async (v0.1.22)
step (v0.0.5)
node-block (v0.1.4)

$ time node bench-async.js
real  0m0.848s
user  0m0.826s
sys  0m0.027s
$ time node bench-step.js
real  0m0.263s
user  0m0.241s
sys  0m0.022s
$ time node bench-node-block.js
real  0m0.370s
user  0m0.353s
sys  0m0.018s

グラフは右に長いほど遅くなります。
step がとても速いです。
一応 async と node-block のフォローをしとくと、async は多機能で、 node-block は step より書きやすいと思います。

[ bench-async.js ]

'use strict';
var async = require('async');

var loopCount = 20000;
(function serialLoop() {
  if (loopCount-- <= 0) return;
  async.series([
    function (cb) {
      process.nextTick(cb);
    },
    function(cb) {
      async.parallel([
        function(cb){process.nextTick(cb)},
        function(cb){process.nextTick(cb)}
      ], cb);
    },
    function(cb) {
      async.parallel([
        function(cb){process.nextTick(cb)},
        function(cb){process.nextTick(cb)},
        function(cb){process.nextTick(cb)}
      ], cb);
    },
    function(cb) {
      async.parallel([
        function(cb){process.nextTick(cb)},
        function(cb){process.nextTick(cb)},
        function(cb){process.nextTick(cb)},
        function(cb){process.nextTick(cb)}
      ], cb);
    }
  ],
  serialLoop);
})();

[ bench-step.js ]

'use strict';
var Step = require('step');

var loopCount = 20000;
(function serialLoop() {
  if (loopCount-- <= 0) return;
  Step(
    function () {
      process.nextTick(this);
    },
    function() {
      process.nextTick(this.parallel());
      process.nextTick(this.parallel());
    },
    function() {
      process.nextTick(this.parallel());
      process.nextTick(this.parallel());
      process.nextTick(this.parallel());
    },
    function() {
      process.nextTick(this.parallel());
      process.nextTick(this.parallel());
      process.nextTick(this.parallel());
      process.nextTick(this.parallel());
    },
    function() {
      serialLoop();
    }
  );
})();

[ bench-node-block.js ]

'use strict';
var block = require('node-block').block;

var loopCount = 20000;
(function serialLoop() {
  if (loopCount-- <= 0) return;
  block(
    function() {
      process.nextTick(this.async());
    },
    function() {
      process.nextTick(this.async());
      process.nextTick(this.async());
    },
    function() {
      process.nextTick(this.async());
      process.nextTick(this.async());
      process.nextTick(this.async());
    },
    function() {
      process.nextTick(this.async());
      process.nextTick(this.async());
      process.nextTick(this.async());
      process.nextTick(this.async());
    }
  )(serialLoop);
})();