Call with and without prototype

JavaScript performance comparison

Revision 3 of this test case created

Preparation code

<script>
  var Event = function() {
      var listeners = {};
      this.getListeners = function() {
        return listeners;
      };
      };
  Event.prototype.on = function(eventName, listener) {
    var listeners = this.getListeners();
    if (!listeners[eventName]) {
      listeners[eventName] = [];
    }
    listeners[eventName].push(listener);
    return this;
  };
  Event.prototype.once = function(eventName, listener) {

    var that = this,
        wrapped;

    wrapped = function() {
      listener.apply(that, arguments);
      that.off(eventName, wrapped);
    };
    return this.on(eventName, wrapped);

  };
  Event.prototype.off = function(eventName, listener) {
    var i, listeners = this.getListeners(),
        lastIndex = listeners[eventName] ? listeners[eventName].length : 0;

    if (listener) {
      while (lastIndex > 0) {
        lastIndex -= 1;
        if (listeners[eventName][lastIndex] === listener) {
          listeners[eventName].splice(lastIndex, 1);
        }
      }
    }
    if (!listener || (listeners[eventName] && listeners[eventName].length === 0)) {
      delete listeners[eventName];
    }
    return this;
  };
  Event.prototype.trigger = function(eventName, data) {
    var i, listeners = this.getListeners(),
        lastIndex = listeners[eventName] ? listeners[eventName].length : 0;

    while (lastIndex > 0) {
      lastIndex -= 1;
      if (listeners[eventName]) {
        listeners[eventName][lastIndex](data);
      }
    }
    return this;
  };


  var oEvent = function() {

      var listeners = {};
      this.on = function(eventName, listener) {
        if (!listeners[eventName]) {
          listeners[eventName] = [];
        }
        listeners[eventName].push(listener);
        return this;
      };
      this.once = function(eventName, listener) {

        var that = this,
            wrapped;
        wrapped = function() {
          listener.apply(that, arguments);
          that.off(eventName, wrapped);
        };
        return this.on(eventName, wrapped);

      };
      this.off = function(eventName, listener) {
        var i, lastIndex = listeners[eventName] ? listeners[eventName].length : 0;

        if (listener) {
          while (lastIndex > 0) {
            lastIndex -= 1;
            if (listeners[eventName][lastIndex] === listener) {
              listeners[eventName].splice(lastIndex, 1);
            }
          }
        }
        if (!listener || (listeners[eventName] && listeners[eventName].length === 0)) {
          delete listeners[eventName];
        }
        return this;
      };
      this.trigger = function(eventName, data) {
        var i, lastIndex = listeners[eventName] ? listeners[eventName].length : 0;

        while (lastIndex > 0) {
          lastIndex -= 1;
          if (listeners[eventName]) {
            listeners[eventName][lastIndex](data);
          }
        }
        return this;
      };
      };
</script>

Test runner

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

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
Prototype
var a = new Event;
var b = new Event;
var c = new Event;
var d = new Event;
var e = new Event;
var f = new Event;
var g = new Event;

a.on('test', function() {});
a.once('test', function() {});
a.trigger('test', function() {});
a.off('test', function() {});

b.on('test', function() {});
b.once('test', function() {});
b.trigger('test', function() {});
b.off('test', function() {});

c.on('test', function() {});
c.once('test', function() {});
c.trigger('test', function() {});
c.off('test', function() {});

d.on('test', function() {});
d.once('test', function() {});
d.trigger('test', function() {});
d.off('test', function() {});

e.on('test', function() {});
e.once('test', function() {});
e.trigger('test', function() {});
e.off('test', function() {});

f.on('test', function() {});
f.once('test', function() {});
f.trigger('test', function() {});
f.off('test', function() {});

g.on('test', function() {});
g.once('test', function() {});
g.trigger('test', function() {});
g.off('test', function() {});
pending…
Without prototype
var a = new oEvent;
var b = new oEvent;
var c = new oEvent;
var d = new oEvent;
var e = new oEvent;
var f = new oEvent;
var g = new oEvent;

a.on('test', function() {});
a.once('test', function() {});
a.trigger('test', function() {});
a.off('test', function() {});

b.on('test', function() {});
b.once('test', function() {});
b.trigger('test', function() {});
b.off('test', function() {});

c.on('test', function() {});
c.once('test', function() {});
c.trigger('test', function() {});
c.off('test', function() {});

d.on('test', function() {});
d.once('test', function() {});
d.trigger('test', function() {});
d.off('test', function() {});

e.on('test', function() {});
e.once('test', function() {});
e.trigger('test', function() {});
e.off('test', function() {});

f.on('test', function() {});
f.once('test', function() {});
f.trigger('test', function() {});
f.off('test', function() {});

g.on('test', function() {});
g.once('test', function() {});
g.trigger('test', function() {});
g.off('test', function() {});
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. Here’s a list of current revisions for this page:

0 comments

Add a comment