Skip to content

Commit e0835c9

Browse files
committed
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: #985 Reviewed-By: Vladimir Kurchatkin <[email protected]>
1 parent 9741291 commit e0835c9

File tree

2 files changed

+45
-43
lines changed

2 files changed

+45
-43
lines changed

src/node.js

+44-42
Original file line numberDiff line numberDiff line change
@@ -340,65 +340,67 @@
340340
function _tickCallback() {
341341
var callback, threw, tock;
342342

343-
scheduleMicrotasks();
344-
345-
while (tickInfo[kIndex] < tickInfo[kLength]) {
346-
tock = nextTickQueue[tickInfo[kIndex]++];
347-
callback = tock.callback;
348-
threw = true;
349-
try {
350-
callback();
351-
threw = false;
352-
} finally {
353-
if (threw)
343+
do {
344+
while (tickInfo[kIndex] < tickInfo[kLength]) {
345+
tock = nextTickQueue[tickInfo[kIndex]++];
346+
callback = tock.callback;
347+
threw = true;
348+
try {
349+
callback();
350+
threw = false;
351+
} finally {
352+
if (threw)
353+
tickDone();
354+
}
355+
if (1e4 < tickInfo[kIndex])
354356
tickDone();
355357
}
356-
if (1e4 < tickInfo[kIndex])
357-
tickDone();
358-
}
359-
360-
tickDone();
358+
tickDone();
359+
_runMicrotasks();
360+
emitPendingUnhandledRejections();
361+
} while (tickInfo[kLength] !== 0);
361362
}
362363

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

366-
scheduleMicrotasks();
367-
368-
while (tickInfo[kIndex] < tickInfo[kLength]) {
369-
tock = nextTickQueue[tickInfo[kIndex]++];
370-
callback = tock.callback;
371-
domain = tock.domain;
372-
if (domain)
373-
domain.enter();
374-
threw = true;
375-
try {
376-
callback();
377-
threw = false;
378-
} finally {
379-
if (threw)
367+
do {
368+
while (tickInfo[kIndex] < tickInfo[kLength]) {
369+
tock = nextTickQueue[tickInfo[kIndex]++];
370+
callback = tock.callback;
371+
domain = tock.domain;
372+
if (domain)
373+
domain.enter();
374+
threw = true;
375+
try {
376+
callback();
377+
threw = false;
378+
} finally {
379+
if (threw)
380+
tickDone();
381+
}
382+
if (1e4 < tickInfo[kIndex])
380383
tickDone();
384+
if (domain)
385+
domain.exit();
381386
}
382-
if (1e4 < tickInfo[kIndex])
383-
tickDone();
384-
if (domain)
385-
domain.exit();
386-
}
387+
tickDone();
388+
_runMicrotasks();
389+
emitPendingUnhandledRejections();
390+
} while (tickInfo[kLength] !== 0);
391+
}
387392

388-
tickDone();
393+
function TickObject(c) {
394+
this.callback = c;
395+
this.domain = process.domain || null;
389396
}
390397

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

396-
var obj = {
397-
callback: callback,
398-
domain: process.domain || null
399-
};
400-
401-
nextTickQueue.push(obj);
403+
nextTickQueue.push(new TickObject(callback));
402404
tickInfo[kLength]++;
403405
}
404406

test/parallel/test-timers-first-fire.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ setTimeout(function() {
88
var ms = (hr[0] * 1e3) + (hr[1] / 1e6);
99
var delta = ms - TIMEOUT;
1010
console.log('timer fired in', delta);
11-
assert.ok(delta > 0, 'Timer fired early');
11+
assert.ok(delta > -0.5, 'Timer fired early');
1212
}, TIMEOUT);

0 commit comments

Comments
 (0)