Skip to content

Commit 2e92f6f

Browse files
RaisinTentargos
authored andcommitted
timers: use ref counts to count timers
The additional objects that were getting added and deleted from the activeTimersMap object were slowing down the rest of the timers code, so this change falls back to using the ref counts to count the active timers inside process.getActiveResourcesInfo(). Fixes: #41219 Signed-off-by: Darshan Sen <[email protected]> PR-URL: #41231 Reviewed-By: Anatoli Papirovski <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 09c25bb commit 2e92f6f

File tree

3 files changed

+14
-22
lines changed

3 files changed

+14
-22
lines changed

lib/internal/bootstrap/node.js

+5-7
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,16 @@
3939
setupPrepareStackTrace();
4040

4141
const {
42+
Array,
4243
ArrayPrototypeConcat,
43-
ArrayPrototypeFilter,
44-
ArrayPrototypeMap,
44+
ArrayPrototypeFill,
4545
FunctionPrototypeCall,
4646
JSONParse,
4747
ObjectDefineProperty,
4848
ObjectDefineProperties,
4949
ObjectGetPrototypeOf,
5050
ObjectPreventExtensions,
5151
ObjectSetPrototypeOf,
52-
ObjectValues,
5352
ReflectGet,
5453
ReflectSet,
5554
SymbolToStringTag,
@@ -156,13 +155,12 @@ const rawMethods = internalBinding('process_methods');
156155
process._getActiveHandles = rawMethods._getActiveHandles;
157156

158157
process.getActiveResourcesInfo = function() {
158+
const timerCounts = internalTimers.getTimerCounts();
159159
return ArrayPrototypeConcat(
160160
rawMethods._getActiveRequestsInfo(),
161161
rawMethods._getActiveHandlesInfo(),
162-
ArrayPrototypeMap(
163-
ArrayPrototypeFilter(ObjectValues(internalTimers.activeTimersMap),
164-
({ resource }) => resource.hasRef()),
165-
({ type }) => type));
162+
ArrayPrototypeFill(new Array(timerCounts.timeoutCount), 'Timeout'),
163+
ArrayPrototypeFill(new Array(timerCounts.immediateCount), 'Immediate'));
166164
};
167165

168166
// TODO(joyeecheung): remove these

lib/internal/timers.js

+9-12
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,6 @@ const kRefed = Symbol('refed');
139139
// Create a single linked list instance only once at startup
140140
const immediateQueue = new ImmediateList();
141141

142-
// Object map containing timers
143-
//
144-
// - key = asyncId
145-
// - value = { type, resource }
146-
const activeTimersMap = ObjectCreate(null);
147-
148142
let nextExpiry = Infinity;
149143
let refCount = 0;
150144

@@ -166,7 +160,6 @@ function initAsyncResource(resource, type) {
166160
resource[trigger_async_id_symbol] = getDefaultTriggerAsyncId();
167161
if (initHooksExist())
168162
emitInit(asyncId, type, triggerAsyncId, resource);
169-
activeTimersMap[asyncId] = { type, resource };
170163
}
171164

172165
// Timer constructor function.
@@ -478,7 +471,6 @@ function getTimerCallbacks(runNextTicks) {
478471

479472
if (destroyHooksExist())
480473
emitDestroy(asyncId);
481-
delete activeTimersMap[asyncId];
482474

483475
outstandingQueue.head = immediate = immediate._idleNext;
484476
}
@@ -551,7 +543,6 @@ function getTimerCallbacks(runNextTicks) {
551543

552544
if (destroyHooksExist())
553545
emitDestroy(asyncId);
554-
delete activeTimersMap[asyncId];
555546
}
556547
continue;
557548
}
@@ -580,7 +571,6 @@ function getTimerCallbacks(runNextTicks) {
580571

581572
if (destroyHooksExist())
582573
emitDestroy(asyncId);
583-
delete activeTimersMap[asyncId];
584574
}
585575
}
586576

@@ -648,6 +638,13 @@ class Immediate {
648638
}
649639
}
650640

641+
function getTimerCounts() {
642+
return {
643+
timeoutCount: refCount,
644+
immediateCount: immediateInfo[kRefCount],
645+
};
646+
}
647+
651648
module.exports = {
652649
TIMEOUT_MAX,
653650
kTimeout: Symbol('timeout'), // For hiding Timeouts on other internals.
@@ -670,9 +667,9 @@ module.exports = {
670667
active,
671668
unrefActive,
672669
insert,
673-
activeTimersMap,
674670
timerListMap,
675671
timerListQueue,
676672
decRefCount,
677-
incRefCount
673+
incRefCount,
674+
getTimerCounts,
678675
};

lib/timers.js

-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ const {
4545
kRefed,
4646
kHasPrimitive,
4747
getTimerDuration,
48-
activeTimersMap,
4948
timerListMap,
5049
timerListQueue,
5150
immediateQueue,
@@ -88,7 +87,6 @@ function unenroll(item) {
8887
// Fewer checks may be possible, but these cover everything.
8988
if (destroyHooksExist() && item[async_id_symbol] !== undefined)
9089
emitDestroy(item[async_id_symbol]);
91-
delete activeTimersMap[item[async_id_symbol]];
9290

9391
L.remove(item);
9492

@@ -331,7 +329,6 @@ function clearImmediate(immediate) {
331329
if (destroyHooksExist() && immediate[async_id_symbol] !== undefined) {
332330
emitDestroy(immediate[async_id_symbol]);
333331
}
334-
delete activeTimersMap[immediate[async_id_symbol]];
335332

336333
immediate._onImmediate = null;
337334

0 commit comments

Comments
 (0)