Mixin

JavaScript performance comparison

Test case created by

Preparation code


      
      <script>
Benchmark.prototype.setup = function() {
  /**
   * Require the given path.
   *
   * @param {String} path
   * @return {Object} exports
   * @api public
   */
  
  function require(p, parent, orig){
    var path = require.resolve(p)
      , mod = require.modules[path];
  
    // lookup failed
    if (null == path) {
      orig = orig || p;
      parent = parent || 'root';
      throw new Error('failed to require "' + orig + '" from "' + parent + '"');
    }
  
    // perform real require()
    // by invoking the module's
    // registered function
    if (!mod.exports) {
      mod.exports = {};
      mod.client = mod.component = true;
      mod.call(this, mod, mod.exports, require.relative(path));
    }
  
    return mod.exports;
  }
  
  /**
   * Registered modules.
   */
  
  require.modules = {};
  
  /**
   * Registered aliases.
   */
  
  require.aliases = {};
  
  /**
   * Resolve `path`.
   *
   * Lookup:
   *
   *   - PATH/index.js
   *   - PATH.js
   *   - PATH
   *
   * @param {String} path
   * @return {String} path or null
   * @api private
   */
  
  require.resolve = function(path){
    var orig = path
      , reg = path + '.js'
      , regJSON = path + '.json'
      , index = path + '/index.js'
      , indexJSON = path + '/index.json';
  
    return require.modules[reg] && reg
      || require.modules[regJSON] && regJSON
      || require.modules[index] && index
      || require.modules[indexJSON] && indexJSON
      || require.modules[orig] && orig
      || require.aliases[index];
  };
  
  /**
   * Normalize `path` relative to the current path.
   *
   * @param {String} curr
   * @param {String} path
   * @return {String}
   * @api private
   */
  
  require.normalize = function(curr, path) {
    var segs = [];
  
    if ('.' != path.charAt(0)) return path;
  
    curr = curr.split('/');
    path = path.split('/');
  
    for (var i = 0; i < path.length; ++i) {
      if ('..' == path[i]) {
        curr.pop();
      } else if ('.' != path[i] && '' != path[i]) {
        segs.push(path[i]);
      }
    }
  
    return curr.concat(segs).join('/');
  };
  
  /**
   * Register module at `path` with callback `fn`.
   *
   * @param {String} path
   * @param {Function} fn
   * @api private
   */
  
  require.register = function(path, fn){
    require.modules[path] = fn;
  };
  
  /**
   * Alias a module definition.
   *
   * @param {String} from
   * @param {String} to
   * @api private
   */
  
  require.alias = function(from, to){
    var fn = require.modules[from];
    if (!fn) throw new Error('failed to alias "' + from + '", it does not exist');
    require.aliases[to] = from;
  };
  
  /**
   * Return a require function relative to the `parent` path.
   *
   * @param {String} parent
   * @return {Function}
   * @api private
   */
  
  require.relative = function(parent) {
    var p = require.normalize(parent, '..');
  
    /**
     * lastIndexOf helper.
     */
  
    function lastIndexOf(arr, obj){
      var i = arr.length;
      while (i--) {
        if (arr[i] === obj) return i;
      }
      return -1;
    }
  
    /**
     * The relative require() itself.
     */
  
    function fn(path){
      var orig = path;
      path = fn.resolve(path);
      return require(path, parent, orig);
    }
  
    /**
     * Resolve relative to the parent.
     */
  
    fn.resolve = function(path){
      // resolve deps by returning
      // the dep in the nearest "deps"
      // directory
      if ('.' != path.charAt(0)) {
        var segs = parent.split('/');
        var i = lastIndexOf(segs, 'deps') + 1;
        if (!i) i = 0;
        path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
        return path;
      }
      return require.normalize(p, path);
    };
  
    /**
     * Check if module is defined at `path`.
     */
  
    fn.exists = function(path){
      return !! require.modules[fn.resolve(path)];
    };
  
    return fn;
  };require.register("component-emitter/index.js", function(module, exports, require){
  
  /**
   * Expose `Emitter`.
   */
  
  module.exports = Emitter;
  
  /**
   * Initialize a new `Emitter`.
   * 
   * @api public
   */
  
  function Emitter(obj) {
    if (obj) return mixin(obj);
  };
  
  /**
   * Mixin the emitter properties.
   *
   * @param {Object} obj
   * @return {Object}
   * @api private
   */
  
  function mixin(obj) {
    for (var key in Emitter.prototype) {
      obj[key] = Emitter.prototype[key];
    }
    return obj;
  }
  
  /**
   * Listen on the given `event` with `fn`.
   *
   * @param {String} event
   * @param {Function} fn
   * @return {Emitter}
   * @api public
   */
  
  Emitter.prototype.on = function(event, fn){
    this._callbacks = this._callbacks || {};
    (this._callbacks[event] = this._callbacks[event] || [])
      .push(fn);
    return this;
  };
  
  /**
   * Adds an `event` listener that will be invoked a single
   * time then automatically removed.
   *
   * @param {String} event
   * @param {Function} fn
   * @return {Emitter}
   * @api public
   */
  
  Emitter.prototype.once = function(event, fn){
    var self = this;
    this._callbacks = this._callbacks || {};
  
    function on() {
      self.off(event, on);
      fn.apply(this, arguments);
    }
  
    fn._off = on;
    this.on(event, on);
    return this;
  };
  
  /**
   * Remove the given callback for `event` or all
   * registered callbacks.
   *
   * @param {String} event
   * @param {Function} fn
   * @return {Emitter}
   * @api public
   */
  
  Emitter.prototype.off = function(event, fn){
    this._callbacks = this._callbacks || {};
    var callbacks = this._callbacks[event];
    if (!callbacks) return this;
  
    // remove all handlers
    if (1 == arguments.length) {
      delete this._callbacks[event];
      return this;
    }
  
    // remove specific handler
    var i = callbacks.indexOf(fn._off || fn);
    if (~i) callbacks.splice(i, 1);
    return this;
  };
  
  /**
   * Emit `event` with the given args.
   *
   * @param {String} event
   * @param {Mixed} ...
   * @return {Emitter} 
   */
  
  Emitter.prototype.emit = function(event){
    this._callbacks = this._callbacks || {};
    var args = [].slice.call(arguments, 1)
      , callbacks = this._callbacks[event];
  
    if (callbacks) {
      callbacks = callbacks.slice(0);
      for (var i = 0, len = callbacks.length; i < len; ++i) {
        callbacks[i].apply(this, args);
      }
    }
  
    return this;
  };
  
  /**
   * Return array of callbacks for `event`.
   *
   * @param {String} event
   * @return {Array}
   * @api public
   */
  
  Emitter.prototype.listeners = function(event){
    this._callbacks = this._callbacks || {};
    return this._callbacks[event] || [];
  };
  
  /**
   * Check if this emitter has `event` handlers.
   *
   * @param {String} event
   * @return {Boolean}
   * @api public
   */
  
  Emitter.prototype.hasListeners = function(event){
    return !! this.listeners(event).length;
  };
  
  
  });
  require.register("array/array.js", function(module, exports, require){
  /**
   * Module dependencies
   */
  
  var Emitter = require('emitter');
  
  /**
   * Expose `array`
   */
  
  module.exports = array;
  
  /**
   * Array prototype
   */
  
  var proto = Array.prototype;
  
  /**
   * Initalize `array`
   *
   * @param {Array} arr
   * @return {array}
   */
  
  function array(arr) {
    if(!(this instanceof array)) return new array(arr);
    return mixin(arr);
  }
  
  /**
   * Inherit from `Emitter`
   */
  
  Emitter(array.prototype);
  
  /**
   * Removes the last element from an array and returns that element
   *
   * @return {Mixed} removed element
   */
  
  array.prototype.pop = function() {
    var ret = proto.pop.apply(this, arguments);
    this.emit('pop', ret);
    this.emit('remove', ret);
    return ret;
  };
  
  /**
   * Push a value onto the end of the array,
   * returning the length of the array
   *
   * @param {Mixed, ...} elements
   * @return {Number}
   */
  
  array.prototype.push = function() {
    var ret = proto.push.apply(this, arguments),
        args = [].slice.call(arguments);
    this.emit('push', ret);
    for(var i = 0, len = args.length; i < len; i++) this.emit('add', args[i]);
    return ret;
  };
  
  /**
   * Reverses an array in place.
   *
   * @return {Array}
   */
  
  array.prototype.reverse = function() {
    var ret = proto.reverse.apply(this, arguments);
    this.emit('reverse', ret);
    return ret;
  };
  
  /**
   * Removes the first element from an array and returns that element.
   *
   * @return {Mixed}
   */
  
  array.prototype.shift = function() {
    var ret = proto.shift.apply(this, arguments);
    this.emit('shift', ret);
    this.emit('remove', ret);
    return ret;
  };
  
  /**
   * Sorts the elements of an array.
   *
   * @return {Array}
   */
  
  array.prototype.sort = function() {
    var ret = proto.sort.apply(this, arguments);
    this.emit('sort', ret);
    return ret;
  };
  
  /**
   * Adds and/or removes elements from an array.
   *
   * @param {Number} index
   * @param {Number} howMany
   * @param {Mixed, ...} elements
   * @return {Array} removed elements
   */
  
  array.prototype.splice = function() {
    var ret = proto.splice.apply(this, arguments),
        added = [].slice.call(arguments, 2);
    this.emit('splice', ret);
    for(var i = 0, len = ret.length; i < len; i++) this.emit('remove', ret[i]);
    for(    i = 0, len = added.length; i < len; i++) this.emit('add', added[i]);
    return ret;
  };
  
  /**
   * Adds one or more elements to the front of an array
   * and returns the new length of the array.
   *
   * @param {Mixed, ...} elements
   * @return {Number} length
   */
  
  array.prototype.unshift = function() {
    var ret = proto.unshift.apply(this, arguments),
        args = [].slice.call(arguments);
    this.emit('unshift', ret);
    for(var i = 0, len = args.length; i < len; i++) this.emit('add', args[i]);
    return ret;
  };
  
  /**
   * Mixin to `arr`.
   *
   *    var array = require('array');
   *    array(Something.prototype);
   *
   * @param {Object} arr
   * @return {Object} arr
   */
  
  function mixin(arr){
    for (var key in array.prototype)
      arr[key] = array.prototype[key];
    return arr;
  }
  
  });
  require.alias("component-emitter/index.js", "array/deps/emitter/index.js");
  
  require.alias("array/array.js", "array/index.js");
  var array = require('array');
  var arrr = array([]);

};
</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
Normal Array
var arr = [];

arr.push('1', '2');
pending…
Emitting Array
arrr.push('1', '2');
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