Skip to content

Commit

Permalink
Sage/streamlinejs#328 - optimized fn.apply calls for small number of …
Browse files Browse the repository at this point in the history
…args
  • Loading branch information
bjouhier committed Mar 1, 2016
1 parent 7bb74ab commit 2a10c01
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions lib/fibers/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ var g = util.getGlobals('fibers');

var keys = [];

function applyFast(fn, that, args) {
switch (args.length) {
case 1: return fn.call(that, args[0]);
case 2: return fn.call(that, args[0], args[1]);
case 3: return fn.call(that, args[0], args[1], args[2]);
case 4: return fn.call(that, args[0], args[1], args[2], args[3]);
default: return fn.apply(that, args);
}
}

exports.await = function(file, line, object, property, index1, index2, returnArray, args) {
var bound = typeof property !== "function";
var fn = bound ? object[property] : property;
Expand All @@ -18,7 +28,7 @@ exports.await = function(file, line, object, property, index1, index2, returnArr
key = keys[index1] || (keys[index1] = 'fiberized-' + index1);
wrapper = fn[key];
if (!wrapper && bound) {
// second chance for foo.call(bar, _, ...).
// second chance for foo.call(bar, _, ...). Optimize if bar.foo['fiberized-0'] exists
if ((property === 'call') && index1 > 0 && typeof object === 'function') {
var key2 = keys[index1 - 1] || (keys[index1 - 1] = 'fiberized-' + (index1 - 1));
var fn2 = object[key2];
Expand All @@ -30,7 +40,8 @@ exports.await = function(file, line, object, property, index1, index2, returnArr
}
if (wrapper) {
if (g.emitter) wrapper = frameModule.wrap(file, line, wrapper);
if (Array.isArray(args)) return wrapper.apply(object, args);
// streamline < 2.0 does not pass args - return wrapper in this case
if (Array.isArray(args)) return applyFast(wrapper, object, args);
else return bound ? wrapper.bind(object) : wrapper;
}
}
Expand Down Expand Up @@ -86,7 +97,7 @@ function awaitSlow(file, line, object, property, index1, index2, returnArray, ar

// Invoke the function and yield
var frame = g.emitter && frameModule.pushFrame(file, line, fn.name);
fn.apply(that, args);
applyFast(fn, that, args);

if (yielded) {
if (frame) frame.pop();
Expand Down Expand Up @@ -117,7 +128,7 @@ function awaitSlow(file, line, object, property, index1, index2, returnArray, ar
if (!bound && key) {
fn[key] = wrapper;
}
return Array.isArray(args) ? wrapper.apply(object, args) : wrapper;
return Array.isArray(args) ? applyFast(wrapper, object, args) : wrapper;
};

function arityWrapper(template) {
Expand Down Expand Up @@ -173,7 +184,7 @@ var asyncTemplate = arityWrapper(function(fn, index) {
g.context = cx;
cx = null;
try {
val = fn.apply(lthat, largs);
val = applyFast(fn, lthat, largs);
} catch (e) {
err = e;
} finally {
Expand All @@ -196,7 +207,7 @@ exports.new = function(file, line, constructor, index) {
return function() {
var that = Object.create(constructor.prototype);
arguments[index] = true;
exports.await(file, line, null, constructor, index, null, false).apply(that, arguments);
applyFast(exports.await(file, line, null, constructor, index, null, false), that, arguments);
return that;
};
}
Expand Down Expand Up @@ -225,7 +236,7 @@ Function.prototype.apply_['fiberized-0'] = function(dummy, thisObj, args, index)
if (this['fiberized-0']) {
args = Array.prototype.slice.call(args, 0);
args.splice(index != null && index >= 0 ? index : args.length, 0, dummy);
return this['fiberized-0'].apply(thisObj, args);
return applyFast(this['fiberized-0'], thisObj, args);
} else {
return Function.prototype.apply_.call(this, dummy, thisObj, args, index);
}
Expand Down

0 comments on commit 2a10c01

Please sign in to comment.