Skip to content

Commit

Permalink
lib: don't penalize setInterval() common case
Browse files Browse the repository at this point in the history
The common case is where setInterval() is called with two arguments,
the callback and the timeout.  Specifying optional arguments in
the parameter list forces common case calls to go through an arguments
adaptor stack frame.

PR-URL: nodejs#1221
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
  • Loading branch information
bnoordhuis committed Mar 20, 2015
1 parent 31da975 commit 33fea6e
Showing 1 changed file with 28 additions and 30 deletions.
58 changes: 28 additions & 30 deletions lib/timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,52 +229,50 @@ exports.clearTimeout = function(timer) {
};


exports.setInterval = function(callback, repeat, arg1, arg2, arg3) {
exports.setInterval = function(callback, repeat) {
repeat *= 1; // coalesce to number or NaN

if (!(repeat >= 1 && repeat <= TIMEOUT_MAX)) {
repeat = 1; // schedule on next tick, follows browser behaviour
}

var args, i;
var timer = new Timeout(repeat);
var len = arguments.length - 2;
timer._onTimeout = wrapper;
timer._repeat = true;
// Initialize args once for repeated invocation of slow case below
if (len > 3) {
args = new Array(len);
for (i = 0; i < len; i++)
args[i] = arguments[i + 2];
var length = arguments.length;
var ontimeout = callback;
switch (length) {
case 0:
case 1:
case 2:
break;
case 3:
ontimeout = callback.bind(timer, arguments[2]);
break;
case 4:
ontimeout = callback.bind(timer, arguments[2], arguments[3]);
break;
case 5:
ontimeout =
callback.bind(timer, arguments[2], arguments[3], arguments[4]);
break;
default:
var args = new Array(length - 2);
for (var i = 2; i < length; i += 1)
args[i - 2] = arguments[i];
ontimeout = callback.apply.bind(callback, timer, args);
break;
}
timer._onTimeout = wrapper;
timer._repeat = ontimeout;

if (process.domain) timer.domain = process.domain;
exports.active(timer);

return timer;

function wrapper() {
switch (len) {
// fast cases
case 0:
callback.call(this);
break;
case 1:
callback.call(this, arg1);
break;
case 2:
callback.call(this, arg1, arg2);
break;
case 3:
callback.call(this, arg1, arg2, arg3);
break;
// slow case
default:
callback.apply(this, args);
break;
}
timer._repeat.call(this);
// If callback called clearInterval().
if (timer._repeat === false) return;
if (timer._repeat === null) return;
// If timer is unref'd (or was - it's permanently removed from the list.)
if (this._handle) {
this._handle.start(repeat, 0);
Expand Down

0 comments on commit 33fea6e

Please sign in to comment.