From 6810d3ea53484479ac41615653b5cc7af35c5a1f Mon Sep 17 00:00:00 2001 From: Trevor Norris Date: Thu, 26 Feb 2015 22:41:54 -0700 Subject: [PATCH] node: improve performance of nextTick 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. --- src/node.js | 87 +++++++++++++------------ test/parallel/test-timers-first-fire.js | 2 +- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/node.js b/src/node.js index a5a26e96eae252..ec4ddf690403b1 100644 --- a/src/node.js +++ b/src/node.js @@ -321,7 +321,6 @@ callback: runMicrotasksCallback, domain: null }); - tickInfo[kLength]++; microtasksScheduled = true; } @@ -340,52 +339,59 @@ 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) { @@ -393,12 +399,7 @@ if (process._exiting) return; - var obj = { - callback: callback, - domain: process.domain || null - }; - - nextTickQueue.push(obj); + nextTickQueue.push(new TickObject(callback)); tickInfo[kLength]++; } diff --git a/test/parallel/test-timers-first-fire.js b/test/parallel/test-timers-first-fire.js index 357ac88cbca18c..385724b0b08e44 100644 --- a/test/parallel/test-timers-first-fire.js +++ b/test/parallel/test-timers-first-fire.js @@ -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);