process: improve queueMicrotask performance
Optimize the hot code paths of queueMicrotask by not creating unnecessary objects, not looking up properties on frozen primordials, etc. PR-URL: https://github.com/nodejs/node/pull/28093 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
parent
5bad51406d
commit
cde3928a10
@ -134,15 +134,16 @@ class AsyncResource {
|
|||||||
constructor(type, opts = {}) {
|
constructor(type, opts = {}) {
|
||||||
validateString(type, 'type');
|
validateString(type, 'type');
|
||||||
|
|
||||||
if (typeof opts === 'number') {
|
let triggerAsyncId = opts;
|
||||||
opts = { triggerAsyncId: opts, requireManualDestroy: false };
|
let requireManualDestroy = false;
|
||||||
} else if (opts.triggerAsyncId === undefined) {
|
if (typeof opts !== 'number') {
|
||||||
opts.triggerAsyncId = getDefaultTriggerAsyncId();
|
triggerAsyncId = opts.triggerAsyncId === undefined ?
|
||||||
|
getDefaultTriggerAsyncId() : opts.triggerAsyncId;
|
||||||
|
requireManualDestroy = !!opts.requireManualDestroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlike emitInitScript, AsyncResource doesn't supports null as the
|
// Unlike emitInitScript, AsyncResource doesn't supports null as the
|
||||||
// triggerAsyncId.
|
// triggerAsyncId.
|
||||||
const triggerAsyncId = opts.triggerAsyncId;
|
|
||||||
if (!Number.isSafeInteger(triggerAsyncId) || triggerAsyncId < -1) {
|
if (!Number.isSafeInteger(triggerAsyncId) || triggerAsyncId < -1) {
|
||||||
throw new ERR_INVALID_ASYNC_ID('triggerAsyncId', triggerAsyncId);
|
throw new ERR_INVALID_ASYNC_ID('triggerAsyncId', triggerAsyncId);
|
||||||
}
|
}
|
||||||
@ -151,15 +152,14 @@ class AsyncResource {
|
|||||||
this[async_id_symbol] = asyncId;
|
this[async_id_symbol] = asyncId;
|
||||||
this[trigger_async_id_symbol] = triggerAsyncId;
|
this[trigger_async_id_symbol] = triggerAsyncId;
|
||||||
|
|
||||||
// This prop name (destroyed) has to be synchronized with C++
|
|
||||||
const destroyed = { destroyed: false };
|
|
||||||
this[destroyedSymbol] = destroyed;
|
|
||||||
|
|
||||||
if (initHooksExist()) {
|
if (initHooksExist()) {
|
||||||
emitInit(asyncId, type, triggerAsyncId, this);
|
emitInit(asyncId, type, triggerAsyncId, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opts.requireManualDestroy) {
|
if (!requireManualDestroy) {
|
||||||
|
// This prop name (destroyed) has to be synchronized with C++
|
||||||
|
const destroyed = { destroyed: false };
|
||||||
|
this[destroyedSymbol] = destroyed;
|
||||||
registerDestroyHook(this, asyncId, destroyed);
|
registerDestroyHook(this, asyncId, destroyed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,6 +168,8 @@ class AsyncResource {
|
|||||||
const asyncId = this[async_id_symbol];
|
const asyncId = this[async_id_symbol];
|
||||||
emitBefore(asyncId, this[trigger_async_id_symbol]);
|
emitBefore(asyncId, this[trigger_async_id_symbol]);
|
||||||
try {
|
try {
|
||||||
|
if (thisArg === undefined)
|
||||||
|
return fn(...args);
|
||||||
return Reflect.apply(fn, thisArg, args);
|
return Reflect.apply(fn, thisArg, args);
|
||||||
} finally {
|
} finally {
|
||||||
emitAfter(asyncId);
|
emitAfter(asyncId);
|
||||||
@ -175,7 +177,9 @@ class AsyncResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
emitDestroy() {
|
emitDestroy() {
|
||||||
this[destroyedSymbol].destroyed = true;
|
if (this[destroyedSymbol] !== undefined) {
|
||||||
|
this[destroyedSymbol].destroyed = true;
|
||||||
|
}
|
||||||
emitDestroy(this[async_id_symbol]);
|
emitDestroy(this[async_id_symbol]);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -128,15 +128,13 @@ function nextTick(callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let AsyncResource;
|
let AsyncResource;
|
||||||
|
const defaultMicrotaskResourceOpts = { requireManualDestroy: true };
|
||||||
function createMicrotaskResource() {
|
function createMicrotaskResource() {
|
||||||
// Lazy load the async_hooks module
|
// Lazy load the async_hooks module
|
||||||
if (!AsyncResource) {
|
if (AsyncResource === undefined) {
|
||||||
AsyncResource = require('async_hooks').AsyncResource;
|
AsyncResource = require('async_hooks').AsyncResource;
|
||||||
}
|
}
|
||||||
return new AsyncResource('Microtask', {
|
return new AsyncResource('Microtask', defaultMicrotaskResourceOpts);
|
||||||
triggerAsyncId: getDefaultTriggerAsyncId(),
|
|
||||||
requireManualDestroy: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function runMicrotask() {
|
function runMicrotask() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user