Skip to content

Commit 2c49e8b

Browse files
apapirovskidanbev
authored andcommitted
lib: make queueMicrotask faster
No longer create an additional scope within queueMicrotask in order to improve performance. PR-URL: #27032 Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent d3d4e10 commit 2c49e8b

File tree

3 files changed

+59
-15
lines changed

3 files changed

+59
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const bench = common.createBenchmark(main, {
5+
n: [4e5]
6+
});
7+
8+
function main({ n }) {
9+
var j = 0;
10+
11+
function cb() {
12+
j++;
13+
if (j === n)
14+
bench.end(n);
15+
}
16+
17+
bench.start();
18+
for (var i = 0; i < n; i++) {
19+
queueMicrotask(cb);
20+
}
21+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const bench = common.createBenchmark(main, {
4+
n: [12e5]
5+
});
6+
7+
function main({ n }) {
8+
let counter = n;
9+
bench.start();
10+
queueMicrotask(onNextTick);
11+
function onNextTick() {
12+
if (--counter)
13+
queueMicrotask(onNextTick);
14+
else
15+
bench.end(n);
16+
}
17+
}

lib/internal/process/task_queues.js

+21-15
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ const {
3737
} = require('internal/errors').codes;
3838
const FixedQueue = require('internal/fixed_queue');
3939

40+
const FunctionBind = Function.call.bind(Function.prototype.bind);
41+
4042
// *Must* match Environment::TickInfo::Fields in src/env.h.
4143
const kHasTickScheduled = 0;
4244

@@ -149,28 +151,32 @@ function createMicrotaskResource() {
149151
});
150152
}
151153

154+
function runMicrotask() {
155+
this.runInAsyncScope(() => {
156+
const callback = this.callback;
157+
try {
158+
callback();
159+
} catch (error) {
160+
// TODO(devsnek) remove this if
161+
// https://bugs.chromium.org/p/v8/issues/detail?id=8326
162+
// is resolved such that V8 triggers the fatal exception
163+
// handler for microtasks
164+
triggerFatalException(error);
165+
} finally {
166+
this.emitDestroy();
167+
}
168+
});
169+
}
170+
152171
function queueMicrotask(callback) {
153172
if (typeof callback !== 'function') {
154173
throw new ERR_INVALID_ARG_TYPE('callback', 'function', callback);
155174
}
156175

157176
const asyncResource = createMicrotaskResource();
177+
asyncResource.callback = callback;
158178

159-
enqueueMicrotask(() => {
160-
asyncResource.runInAsyncScope(() => {
161-
try {
162-
callback();
163-
} catch (error) {
164-
// TODO(devsnek) remove this if
165-
// https://bugs.chromium.org/p/v8/issues/detail?id=8326
166-
// is resolved such that V8 triggers the fatal exception
167-
// handler for microtasks
168-
triggerFatalException(error);
169-
} finally {
170-
asyncResource.emitDestroy();
171-
}
172-
});
173-
});
179+
enqueueMicrotask(FunctionBind(runMicrotask, asyncResource));
174180
}
175181

176182
module.exports = {

0 commit comments

Comments
 (0)