Skip to content

Commit

Permalink
node: improve performance of nextTick
Browse files Browse the repository at this point in the history
Couple micro optimizations to improve performance of process.nextTick().
Removes ~60ns of execution time.

Also added small threshold to test that allows timer to fire early on
the order if microseconds.

PR-URL: #985
Reviewed-By: Vladimir Kurchatkin <vladimir.kurchatkin@gmail.com>
  • Loading branch information
trevnorris committed Mar 3, 2015
1 parent 9741291 commit e0835c9
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 43 deletions.
86 changes: 44 additions & 42 deletions src/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,65 +340,67 @@
function _tickCallback() {
var callback, threw, tock;

scheduleMicrotasks();

while (tickInfo[kIndex] < tickInfo[kLength]) {
tock = nextTickQueue[tickInfo[kIndex]++];
callback = tock.callback;
threw = true;
try {
callback();
threw = false;
} finally {
if (threw)
do {
while (tickInfo[kIndex] < tickInfo[kLength]) {
tock = nextTickQueue[tickInfo[kIndex]++];
callback = tock.callback;
threw = true;
try {
callback();
threw = false;
} finally {
if (threw)
tickDone();
}
if (1e4 < tickInfo[kIndex])
tickDone();
}
if (1e4 < tickInfo[kIndex])
tickDone();
}

tickDone();
tickDone();
_runMicrotasks();
emitPendingUnhandledRejections();
} while (tickInfo[kLength] !== 0);
}

function _tickDomainCallback() {
var callback, domain, threw, tock;

scheduleMicrotasks();

while (tickInfo[kIndex] < tickInfo[kLength]) {
tock = nextTickQueue[tickInfo[kIndex]++];
callback = tock.callback;
domain = tock.domain;
if (domain)
domain.enter();
threw = true;
try {
callback();
threw = false;
} finally {
if (threw)
do {
while (tickInfo[kIndex] < tickInfo[kLength]) {
tock = nextTickQueue[tickInfo[kIndex]++];
callback = tock.callback;
domain = tock.domain;
if (domain)
domain.enter();
threw = true;
try {
callback();
threw = false;
} finally {
if (threw)
tickDone();
}
if (1e4 < tickInfo[kIndex])
tickDone();
if (domain)
domain.exit();
}
if (1e4 < tickInfo[kIndex])
tickDone();
if (domain)
domain.exit();
}
tickDone();
_runMicrotasks();
emitPendingUnhandledRejections();
} while (tickInfo[kLength] !== 0);
}

tickDone();
function TickObject(c) {
this.callback = c;
this.domain = process.domain || null;
}

function nextTick(callback) {
// on the way out, don't bother. it won't get fired anyway.
if (process._exiting)
return;

var obj = {
callback: callback,
domain: process.domain || null
};

nextTickQueue.push(obj);
nextTickQueue.push(new TickObject(callback));
tickInfo[kLength]++;
}

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-timers-first-fire.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ setTimeout(function() {
var ms = (hr[0] * 1e3) + (hr[1] / 1e6);
var delta = ms - TIMEOUT;
console.log('timer fired in', delta);
assert.ok(delta > 0, 'Timer fired early');
assert.ok(delta > -0.5, 'Timer fired early');
}, TIMEOUT);

0 comments on commit e0835c9

Please sign in to comment.