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
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
3+
constcommon=require('../common.js');
4+
constbench=common.createBenchmark(main,{
5+
n: [4e5]
6+
});
7+
8+
functionmain({ n }){
9+
varj=0;
10+
11+
functioncb(){
12+
j++;
13+
if(j===n)
14+
bench.end(n);
15+
}
16+
17+
bench.start();
18+
for(vari=0;i<n;i++){
19+
queueMicrotask(cb);
20+
}
21+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use strict';
2+
constcommon=require('../common.js');
3+
constbench=common.createBenchmark(main,{
4+
n: [12e5]
5+
});
6+
7+
functionmain({ n }){
8+
letcounter=n;
9+
bench.start();
10+
queueMicrotask(onNextTick);
11+
functiononNextTick(){
12+
if(--counter)
13+
queueMicrotask(onNextTick);
14+
else
15+
bench.end(n);
16+
}
17+
}

‎lib/internal/process/task_queues.js‎

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

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

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

154+
functionrunMicrotask(){
155+
this.runInAsyncScope(()=>{
156+
constcallback=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
functionqueueMicrotask(callback){
153172
if(typeofcallback!=='function'){
154173
thrownewERR_INVALID_ARG_TYPE('callback','function',callback);
155174
}
156175

157176
constasyncResource=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)