From e0835c9cda8ad515e407baff0c3515d6f105fd14 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. PR-URL: https://github.com/iojs/io.js/pull/985 Reviewed-By: Vladimir Kurchatkin --- src/node.js | 86 +++++++++++++++++---------------- test/parallel/test-timers-first-fire.js | 2 +- 2 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/node.js b/src/node.js index a5a26e9..cf52cd1 100644 --- a/src/node.js +++ b/src/node.js @@ -340,52 +340,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 +400,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 357ac88..385724b 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); -- 2.7.4