Skip to content

Commit f2e4f62

Browse files
Ruben Bridgewaterrvagg
authored andcommitted
node: improve process.nextTick performance
Prevent deoptimization of process.nextTick by removing the try finally block. This is not necessary as the next tick queue will be reset anyway, no matter if the callback throws or not. Use a predefined array size prevents resizing the array and is therefor faster. PR-URL: #5092 Reviewed-By: Trevor Norris <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent f706cb0 commit f2e4f62

File tree

4 files changed

+35
-104
lines changed

4 files changed

+35
-104
lines changed

src/node.js

Lines changed: 26 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,26 @@
364364
scheduleMicrotasks();
365365
}
366366

367+
function _combinedTickCallback(args, callback) {
368+
if (args === undefined) {
369+
callback();
370+
} else {
371+
switch (args.length) {
372+
case 1:
373+
callback(args[0]);
374+
break;
375+
case 2:
376+
callback(args[0], args[1]);
377+
break;
378+
case 3:
379+
callback(args[0], args[1], args[2]);
380+
break;
381+
default:
382+
callback.apply(null, args);
383+
}
384+
}
385+
}
386+
367387
// Run callbacks that have no domain.
368388
// Using domains will cause this to be overridden.
369389
function _tickCallback() {
@@ -374,27 +394,10 @@
374394
tock = nextTickQueue[tickInfo[kIndex]++];
375395
callback = tock.callback;
376396
args = tock.args;
377-
// Using separate callback execution functions helps to limit the
378-
// scope of DEOPTs caused by using try blocks and allows direct
397+
// Using separate callback execution functions allows direct
379398
// callback invocation with small numbers of arguments to avoid the
380399
// performance hit associated with using `fn.apply()`
381-
if (args === undefined) {
382-
nextTickCallbackWith0Args(callback);
383-
} else {
384-
switch (args.length) {
385-
case 1:
386-
nextTickCallbackWith1Arg(callback, args[0]);
387-
break;
388-
case 2:
389-
nextTickCallbackWith2Args(callback, args[0], args[1]);
390-
break;
391-
case 3:
392-
nextTickCallbackWith3Args(callback, args[0], args[1], args[2]);
393-
break;
394-
default:
395-
nextTickCallbackWithManyArgs(callback, args);
396-
}
397-
}
400+
_combinedTickCallback(args, callback);
398401
if (1e4 < tickInfo[kIndex])
399402
tickDone();
400403
}
@@ -415,27 +418,10 @@
415418
args = tock.args;
416419
if (domain)
417420
domain.enter();
418-
// Using separate callback execution functions helps to limit the
419-
// scope of DEOPTs caused by using try blocks and allows direct
421+
// Using separate callback execution functions allows direct
420422
// callback invocation with small numbers of arguments to avoid the
421423
// performance hit associated with using `fn.apply()`
422-
if (args === undefined) {
423-
nextTickCallbackWith0Args(callback);
424-
} else {
425-
switch (args.length) {
426-
case 1:
427-
nextTickCallbackWith1Arg(callback, args[0]);
428-
break;
429-
case 2:
430-
nextTickCallbackWith2Args(callback, args[0], args[1]);
431-
break;
432-
case 3:
433-
nextTickCallbackWith3Args(callback, args[0], args[1], args[2]);
434-
break;
435-
default:
436-
nextTickCallbackWithManyArgs(callback, args);
437-
}
438-
}
424+
_combinedTickCallback(args, callback);
439425
if (1e4 < tickInfo[kIndex])
440426
tickDone();
441427
if (domain)
@@ -447,61 +433,6 @@
447433
} while (tickInfo[kLength] !== 0);
448434
}
449435

450-
function nextTickCallbackWith0Args(callback) {
451-
var threw = true;
452-
try {
453-
callback();
454-
threw = false;
455-
} finally {
456-
if (threw)
457-
tickDone();
458-
}
459-
}
460-
461-
function nextTickCallbackWith1Arg(callback, arg1) {
462-
var threw = true;
463-
try {
464-
callback(arg1);
465-
threw = false;
466-
} finally {
467-
if (threw)
468-
tickDone();
469-
}
470-
}
471-
472-
function nextTickCallbackWith2Args(callback, arg1, arg2) {
473-
var threw = true;
474-
try {
475-
callback(arg1, arg2);
476-
threw = false;
477-
} finally {
478-
if (threw)
479-
tickDone();
480-
}
481-
}
482-
483-
function nextTickCallbackWith3Args(callback, arg1, arg2, arg3) {
484-
var threw = true;
485-
try {
486-
callback(arg1, arg2, arg3);
487-
threw = false;
488-
} finally {
489-
if (threw)
490-
tickDone();
491-
}
492-
}
493-
494-
function nextTickCallbackWithManyArgs(callback, args) {
495-
var threw = true;
496-
try {
497-
callback.apply(null, args);
498-
threw = false;
499-
} finally {
500-
if (threw)
501-
tickDone();
502-
}
503-
}
504-
505436
function TickObject(c, args) {
506437
this.callback = c;
507438
this.domain = process.domain || null;
@@ -515,9 +446,9 @@
515446

516447
var args;
517448
if (arguments.length > 1) {
518-
args = [];
449+
args = new Array(arguments.length - 1);
519450
for (var i = 1; i < arguments.length; i++)
520-
args.push(arguments[i]);
451+
args[i - 1] = arguments[i];
521452
}
522453

523454
nextTickQueue.push(new TickObject(callback, args));

test/message/eval_messages.out

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ SyntaxError: Strict mode code may not include a with statement
77
at Object.<anonymous> ([eval]-wrapper:*:*)
88
at Module._compile (module.js:*:*)
99
at node.js:*:*
10-
at nextTickCallbackWith0Args (node.js:*:*)
10+
at _combinedTickCallback (node.js:*:*)
1111
at process._tickCallback (node.js:*:*)
1212
42
1313
42
@@ -20,7 +20,7 @@ Error: hello
2020
at Object.<anonymous> ([eval]-wrapper:*:*)
2121
at Module._compile (module.js:*:*)
2222
at node.js:*:*
23-
at nextTickCallbackWith0Args (node.js:*:*)
23+
at _combinedTickCallback (node.js:*:*)
2424
at process._tickCallback (node.js:*:*)
2525
[eval]:1
2626
throw new Error("hello")
@@ -31,7 +31,7 @@ Error: hello
3131
at Object.<anonymous> ([eval]-wrapper:*:*)
3232
at Module._compile (module.js:*:*)
3333
at node.js:*:*
34-
at nextTickCallbackWith0Args (node.js:*:*)
34+
at _combinedTickCallback (node.js:*:*)
3535
at process._tickCallback (node.js:*:*)
3636
100
3737
[eval]:1
@@ -43,7 +43,7 @@ ReferenceError: y is not defined
4343
at Object.<anonymous> ([eval]-wrapper:*:*)
4444
at Module._compile (module.js:*:*)
4545
at node.js:*:*
46-
at nextTickCallbackWith0Args (node.js:*:*)
46+
at _combinedTickCallback (node.js:*:*)
4747
at process._tickCallback (node.js:*:*)
4848
[eval]:1
4949
var ______________________________________________; throw 10

test/message/nexttick_throw.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
^
55
ReferenceError: undefined_reference_error_maker is not defined
66
at *test*message*nexttick_throw.js:*:*
7-
at nextTickCallbackWith0Args (node.js:*:*)
7+
at _combinedTickCallback (node.js:*:*)
88
at process._tickCallback (node.js:*:*)
99
at Function.Module.runMain (module.js:*:*)
1010
at startup (node.js:*:*)

test/message/stdin_messages.out

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ SyntaxError: Strict mode code may not include a with statement
88
at Object.<anonymous> ([stdin]-wrapper:*:*)
99
at Module._compile (module.js:*:*)
1010
at node.js:*:*
11-
at nextTickCallbackWith0Args (node.js:*:*)
11+
at _combinedTickCallback (node.js:*:*)
1212
at process._tickCallback (node.js:*:*)
1313
42
1414
42
@@ -22,7 +22,7 @@ Error: hello
2222
at Object.<anonymous> ([stdin]-wrapper:*:*)
2323
at Module._compile (module.js:*:*)
2424
at node.js:*:*
25-
at nextTickCallbackWith0Args (node.js:*:*)
25+
at _combinedTickCallback (node.js:*:*)
2626
at process._tickCallback (node.js:*:*)
2727

2828
[stdin]:1
@@ -34,7 +34,7 @@ Error: hello
3434
at Object.<anonymous> ([stdin]-wrapper:*:*)
3535
at Module._compile (module.js:*:*)
3636
at node.js:*:*
37-
at nextTickCallbackWith0Args (node.js:*:*)
37+
at _combinedTickCallback (node.js:*:*)
3838
at process._tickCallback (node.js:*:*)
3939
100
4040

@@ -47,7 +47,7 @@ ReferenceError: y is not defined
4747
at Object.<anonymous> ([stdin]-wrapper:*:*)
4848
at Module._compile (module.js:*:*)
4949
at node.js:*:*
50-
at nextTickCallbackWith0Args (node.js:*:*)
50+
at _combinedTickCallback (node.js:*:*)
5151
at process._tickCallback (node.js:*:*)
5252

5353
[stdin]:1

0 commit comments

Comments
 (0)