Created
November 8, 2017 18:17
-
-
Save refack/bebee71aa40270bbf855b8d2a7e7910d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use strict'; | |
| const common = require('../common.js'); | |
| const assert = require('assert'); | |
| const bench = common.createBenchmark(main, { | |
| count: [0, 1, 2, 3, 4, 5], | |
| method: ['call-spread', 'unwind'], | |
| context: ['context', 'null'], | |
| isFn: [0, 1], | |
| millions: [50] | |
| }); | |
| function makeTest(count, isFn, ctx) { | |
| function test(arg1, arg2, arg3, arg4, arg5) { | |
| const args = [arg1, arg2, arg3, arg4, arg5]; | |
| assert.strictEqual(args[count], undefined); | |
| assert.strictEqual(this, ctx); | |
| }; | |
| if (isFn) { | |
| return test | |
| } else { | |
| return [test, test]; | |
| } | |
| } | |
| function arrayClone(arr, n) { | |
| var copy = new Array(n); | |
| for (var i = 0; i < n; ++i) | |
| copy[i] = arr[i]; | |
| return copy; | |
| } | |
| function emitNone(handler, isFn, self) { | |
| if (isFn) | |
| handler.call(self); | |
| else { | |
| var len = handler.length; | |
| var listeners = arrayClone(handler, len); | |
| for (var i = 0; i < len; ++i) | |
| listeners[i].call(self); | |
| } | |
| } | |
| function emitOne(handler, isFn, self, arg1) { | |
| if (isFn) | |
| handler.call(self, arg1); | |
| else { | |
| var len = handler.length; | |
| var listeners = arrayClone(handler, len); | |
| for (var i = 0; i < len; ++i) | |
| listeners[i].call(self, arg1); | |
| } | |
| } | |
| function emitTwo(handler, isFn, self, arg1, arg2) { | |
| if (isFn) | |
| handler.call(self, arg1, arg2); | |
| else { | |
| var len = handler.length; | |
| var listeners = arrayClone(handler, len); | |
| for (var i = 0; i < len; ++i) | |
| listeners[i].call(self, arg1, arg2); | |
| } | |
| } | |
| function emitThree(handler, isFn, self, arg1, arg2, arg3) { | |
| if (isFn) | |
| handler.call(self, arg1, arg2, arg3); | |
| else { | |
| var len = handler.length; | |
| var listeners = arrayClone(handler, len); | |
| for (var i = 0; i < len; ++i) | |
| listeners[i].call(self, arg1, arg2, arg3); | |
| } | |
| } | |
| function emitFour(handler, isFn, self, arg1, arg2, arg3, arg4) { | |
| if (isFn) | |
| handler.call(self, arg1, arg2, arg3, arg4); | |
| else { | |
| var len = handler.length; | |
| var listeners = arrayClone(handler, len); | |
| for (var i = 0; i < len; ++i) | |
| listeners[i].call(self, arg1, arg2, arg3, arg4); | |
| } | |
| } | |
| function emitFive(handler, isFn, self, arg1, arg2, arg3, arg4, arg5) { | |
| if (isFn) | |
| handler.call(self, arg1, arg2, arg3, arg4, arg5); | |
| else { | |
| var len = handler.length; | |
| var listeners = arrayClone(handler, len); | |
| for (var i = 0; i < len; ++i) | |
| listeners[i].call(self, arg1, arg2, arg3, arg4, arg5); | |
| } | |
| } | |
| function emitMany(handler, isFn, self, args) { | |
| if (isFn) | |
| handler.apply(self, args); | |
| else { | |
| var len = handler.length; | |
| var listeners = arrayClone(handler, len); | |
| for (var i = 0; i < len; ++i) | |
| listeners[i].apply(self, args); | |
| } | |
| } | |
| function emitManyBind(handler, isFn, self, args) { | |
| if (isFn) { | |
| handler.bind(self); | |
| handler(...args); | |
| } else { | |
| var len = handler.length; | |
| var listeners = arrayClone(handler, len); | |
| for (var i = 0; i < len; ++i) | |
| listeners[i].apply(self, args); | |
| } | |
| } | |
| function main(conf) { | |
| const n = conf.millions * 1e6; | |
| const ctx = conf.context === 'context' ? {} : null; | |
| const fn = makeTest(conf.count, conf.isFn, ctx); | |
| const args = new Array(conf.count); | |
| for (let i = 0; i < conf.count; i++) | |
| args[i] = i; | |
| switch (conf.method) { | |
| case '': | |
| // Empty string falls through to next line as default, mostly for tests. | |
| case 'call-spread': | |
| bench.start(); | |
| for (let i = 0; i < n; i++) { | |
| fn.apply(ctx, args); | |
| } | |
| bench.end(n / 1e6); | |
| break; | |
| case 'unwind': | |
| bench.start(); | |
| for (let i = 0; i < n; i++) { | |
| switch (args.length) { | |
| case 0: | |
| emitNone(fn, conf.isFn, ctx); | |
| break; | |
| case 1: | |
| emitOne(fn, conf.isFn, ctx, args[0]); | |
| break; | |
| case 2: | |
| emitTwo(fn, conf.isFn, ctx, args[0], args[1]); | |
| break; | |
| case 3: | |
| emitThree(fn, conf.isFn, ctx, args[0], args[1], args[2]); | |
| break; | |
| case 4: | |
| emitFour(fn, conf.isFn, ctx, args[0], args[1], args[2], args[3]); | |
| break; | |
| case 5: | |
| emitFive(fn, conf.isFn, ctx, args[0], args[1], args[2], args[3], args[4]); | |
| break; | |
| default: | |
| throw new Error('Unexpected arg count'); | |
| } | |
| } | |
| bench.end(n / 1e6); | |
| break; | |
| default: | |
| throw new Error('Unexpected method'); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment