Slice In Emit

JavaScript performance comparison

Revision 2 of this test case created by Robert K

Preparation code

 
<script>
Benchmark.prototype.setup = function() {
    var subscriber = {
      fooNoArguments: function() {},
      fooOneArgument: function(foo) {},
      fooMultipleArguments: function(foo, bar, baz) {},
    };
   
    function Subscription(subscriber, message) {
      this.subscriber = subscriber;
      this.message = message;
    }
   
    var arraySlice = Array.prototype.slice;
   
    var EmitterSlice = {
      emit: function(event, data1, data2, data3, data4) {
        var eventSubscriptions = this.subscriptionsFor(event);
        var length, idx;
        var subscription, subscriber, handler;
        var args;
   
        if (this[event]) {
          if (data1 === undefined) {
            this[event]();
          } else if (data2 === undefined) {
            this[event](data1);
          } else if (data3 === undefined) {
            this[event](data1, data2);
          } else if (data4 === undefined) {
            this[event](data1, data2, data3);
          } else {
            args = arraySlice.call(arguments, 1);
            this[event].apply(this, args);
          }
        }
   
        if (eventSubscriptions) {
          length = eventSubscriptions.length;
          for (idx = 0; idx < length; idx++) {
            subscription = eventSubscriptions[idx];
            subscriber = subscription.subscriber;
            handler = subscription.message;
   
            if (typeof handler === 'string') {
              if (data1 === undefined) {
                subscriber[handler]();
              } else if (data2 === undefined) {
                subscriber[handler](data1);
              } else if (data3 === undefined) {
                subscriber[handler](data1, data2);
              } else if (data4 === undefined) {
                subscriber[handler](data1, data2, data3);
              } else {
                if (!args) {
                  args = arraySlice.call(arguments, 1);
                }
   
                subscriber[handler].apply(subscriber, args);
              }
            } else {
              if (data1 === undefined) {
                handler.call(subscriber);
              } else if (data2 === undefined) {
                handler.call(subscriber, data1);
              } else if (data3 === undefined) {
                handler.call(subscriber, data1, data2);
              } else if (data4 === undefined) {
                handler.call(subscriber, data1, data2, data3);
              } else {
                if (!args) {
                  args = arraySlice.call(arguments, 1);
                }
   
                handler.apply(subscriber, args);
              }
            }
          }
        }
      },
   
      subscriptionsFor: function(event) {
        return this._subscriptionsMap ? this._subscriptionsMap[event] : null;
      },
   
      _subscriptionsMap: {
        fooNoArguments: [
          new Subscription(subscriber, 'fooNoArguments'),
          new Subscription(subscriber, 'fooNoArguments'),
          new Subscription(subscriber, 'fooNoArguments')
        ],
        fooOneArgument: [
          new Subscription(subscriber, 'fooOneArgument'),
          new Subscription(subscriber, 'fooOneArgument'),
          new Subscription(subscriber, 'fooOneArgument')
        ],
        fooMultipleArguments: [
          new Subscription(subscriber, 'fooMultipleArguments'),
          new Subscription(subscriber, 'fooMultipleArguments'),
          new Subscription(subscriber, 'fooMultipleArguments')
        ]
      }
    };
   
    var EmitterInlinedSlice = {
      emit: function(event, data1, data2, data3, data4) {
        var eventSubscriptions = this.subscriptionsFor(event);
        var length, idx;
        var subscription, subscriber, handler;
        var args, argsLength;
   
        if (this[event]) {
          if (data1 === undefined) {
            this[event]();
          } else if (data2 === undefined) {
            this[event](data1);
          } else if (data3 === undefined) {
            this[event](data1, data2);
          } else if (data4 === undefined) {
            this[event](data1, data2, data3);
          } else {
            argsLength = arguments.length;
            args = new Array(argsLength - 1);
            for (var i = 1; i < argsLength; i++) args[i - 1] = arguments[i];
            this[event].apply(this, args);
          }
        }
   
        if (eventSubscriptions) {
          length = eventSubscriptions.length;
          for (idx = 0; idx < length; idx++) {
            subscription = eventSubscriptions[idx];
            subscriber = subscription.subscriber;
            handler = subscription.message;
   
            if (typeof handler === 'string') {
              if (data1 === undefined) {
                subscriber[handler]();
              } else if (data2 === undefined) {
                subscriber[handler](data1);
              } else if (data3 === undefined) {
                subscriber[handler](data1, data2);
              } else if (data4 === undefined) {
                subscriber[handler](data1, data2, data3);
              } else {
                if (!args) {
                  argsLength = arguments.length;
                  args = new Array(argsLength - 1);
                  for (var i = 1; i < argsLength; i++) args[i - 1] = arguments[i];
                }
   
                subscriber[handler].apply(subscriber, args);
              }
            } else {
              if (data1 === undefined) {
                handler.call(subscriber);
              } else if (data2 === undefined) {
                handler.call(subscriber, data1);
              } else if (data3 === undefined) {
                handler.call(subscriber, data1, data2);
              } else if (data4 === undefined) {
                handler.call(subscriber, data1, data2, data3);
              } else {
                if (!args) {
                  argsLength = arguments.length;
                  args = new Array(argsLength - 1);
                  for (var i = 1; i < argsLength; i++) args[i - 1] = arguments[i];
                }
   
                handler.apply(subscriber, args);
              }
            }
          }
        }
      },
   
      subscriptionsFor: function(event) {
        return this._subscriptionsMap ? this._subscriptionsMap[event] : null;
      },
   
      _subscriptionsMap: {
        fooNoArguments: [
          new Subscription(subscriber, 'fooNoArguments'),
          new Subscription(subscriber, 'fooNoArguments'),
          new Subscription(subscriber, 'fooNoArguments')
        ],
        fooOneArgument: [
          new Subscription(subscriber, 'fooOneArgument'),
          new Subscription(subscriber, 'fooOneArgument'),
          new Subscription(subscriber, 'fooOneArgument')
        ],
        fooMultipleArguments: [
          new Subscription(subscriber, 'fooMultipleArguments'),
          new Subscription(subscriber, 'fooMultipleArguments'),
          new Subscription(subscriber, 'fooMultipleArguments')
        ]
      }
    };
   
    var _workerArray = new Array(10);
   
    var EmitterStaticSlice = {
      emit: function(event, data1, data2, data3, data4) {
        var eventSubscriptions = this.subscriptionsFor(event);
        var length, idx;
        var subscription, subscriber, handler;
        var a = arguments, al = arguments.length;
        var args = null;
   
        if (this[event]) {
          if (data1 === undefined) {
            this[event]();
          } else if (data2 === undefined) {
            this[event](data1);
          } else if (data3 === undefined) {
            this[event](data1, data2);
          } else if (data4 === undefined) {
            this[event](data1, data2, data3);
          } else {
            argsLength = arguments.length;
            for (var i = 1; i < argsLength; i++) args[i - 1] = arguments[i];
            args.length = i - 1;
            this[event].apply(this, args);
          }
        }
   
        if (eventSubscriptions) {
          length = eventSubscriptions.length;
          for (idx = 0; idx < length; idx++) {
            subscription = eventSubscriptions[idx];
            subscriber = subscription.subscriber;
            handler = subscription.message;
   
            if (typeof handler === 'string') {
              if (data1 === undefined) {
                subscriber[handler]();
              } else if (data2 === undefined) {
                subscriber[handler](data1);
              } else if (data3 === undefined) {
                subscriber[handler](data1, data2);
              } else if (data4 === undefined) {
                subscriber[handler](data1, data2, data3);
              } else {
                if (!args) {
                  argsLength = arguments.length;
                  args = _workerArray;
                  for (var i = 1; i < argsLength; i++) args[i - 1] = arguments[i];
                  args.length = i - 1;
                }
   
                subscriber[handler].apply(subscriber, args);
              }
            } else {
              if (data1 === undefined) {
                handler.call(subscriber);
              } else if (data2 === undefined) {
                handler.call(subscriber, data1);
              } else if (data3 === undefined) {
                handler.call(subscriber, data1, data2);
              } else if (data4 === undefined) {
                handler.call(subscriber, data1, data2, data3);
              } else {
                if (!args) {
                  argsLength = arguments.length;
                  args = _workerArray;
                  for (var i = 1; i < argsLength; i++) args[i - 1] = arguments[i];
                  args.length = i - 1;
                }
   
                handler.apply(subscriber, args);
              }
            }
          }
        }
      },
   
      subscriptionsFor: function(event) {
        return this._subscriptionsMap ? this._subscriptionsMap[event] : null;
      },
   
      _subscriptionsMap: {
        fooNoArguments: [
          new Subscription(subscriber, 'fooNoArguments'),
          new Subscription(subscriber, 'fooNoArguments'),
          new Subscription(subscriber, 'fooNoArguments')
        ],
        fooOneArgument: [
          new Subscription(subscriber, 'fooOneArgument'),
          new Subscription(subscriber, 'fooOneArgument'),
          new Subscription(subscriber, 'fooOneArgument')
        ],
        fooMultipleArguments: [
          new Subscription(subscriber, 'fooMultipleArguments'),
          new Subscription(subscriber, 'fooMultipleArguments'),
          new Subscription(subscriber, 'fooMultipleArguments')
        ]
      }
    };
   
};
</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
Slice
EmitterSlice.emit('fooMultipleArguments', 'wawt', 'foo', 'baz', 'bar', 'lulz');
pending…
Inlined Slice
EmitterInlinedSlice.emit('fooMultipleArguments', 'wawt', 'foo', 'baz', 'bar', 'lulz');
pending…
Static Inlined Slice
EmitterStaticSlice.emit('fooMultipleArguments', 'wawt', 'foo', 'baz', 'bar', 'lulz');
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