nextTick vs setZeroTimeout vs setTimeout

JavaScript performance comparison

Test case created by stagas

Preparation code

<script>
  // setup
  var iterations = 1000
    , n = iterations
    ;
  
  // nextTick - by stagas / public domain
  var nextTick = (function () {
    var queue = []
      , dirty = false
      , fn
      , hasPostMessage = !!window.postMessage
      , messageName = 'nexttick';
    function flushQueue () {
      while (fn = queue.shift()) {
        fn();
      }
      dirty = false;
    }
    var trigger = (function () {
      return hasPostMessage
        ? function () { window.postMessage(messageName, '*') }
        : function () { setTimeout(function () { processQueue(); }, 0) };
    }());
    var processQueue = (function () {
      return hasPostMessage
        ? function (event) {
            if (event.source === window && event.data === messageName) {
              event.stopPropagation();
              flushQueue();
            }
          }
        : flushQueue;
    })();
    function nextTick (fn) {
      queue.push(fn);
      if (dirty) return;
      dirty = true;
      trigger();
    }
  
    hasPostMessage
      && (nextTick.listener = window.addEventListener('message', processQueue, true));
  
    nextTick.removeListener = function () {
      window.removeEventListener('message', processQueue, true);
    }
  
    return nextTick;
  })();
  
  // setZeroTimeout - L. David Baron <dbaron@dbaron.org>
  var setZeroTimeout = (function() {
    var timeouts = [];
    var messageName = "zero-timeout-message";
  
    // Like setTimeout, but only takes a function argument.  There's
    // no time argument (always zero) and no arguments (you have to
    // use a closure).
    function setZeroTimeout(fn) {
      timeouts.push(fn);
      window.postMessage(messageName, "*");
    }
  
    function handleMessage(event) {
      if (event.source == window && event.data == messageName) {
        event.stopPropagation();
        if (timeouts.length > 0) {
          var fn = timeouts.shift();
          fn();
        }
      }
    }
  
    window.addEventListener("message", handleMessage, true);
  
    setZeroTimeout.removeListener = function () {
      window.removeEventListener('message', handleMessage, true);  
    }
    
    // Add the one thing we want added to the window object.
    return setZeroTimeout;
  })();
</script>
      
<script>
Benchmark.prototype.setup = function() {
  n = iterations;
  
  

};

Benchmark.prototype.teardown = function() {
  nextTick.removeListener();
  setZeroTimeout.removeListener();

};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
nextTick
// async test
// nextTick
(function loop (n) {
  if (--n) nextTick(loop)
  else deferred.resolve();
})(n);
pending…
setZeroTimeout
// async test
// setZeroTimeout
(function loop (n) {
  if (--n) setZeroTimeout(loop)
  else deferred.resolve();
})(n);
pending…
setTimeout
// async test
// setTimeout
(function loop (n) {
  if (--n) setTimeout(loop, 0)
  else deferred.resolve();
})(n);
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL.

0 Comments