Hypothesis
The format string scanner does createDebug.formatters[char] on every format specifier. createDebug is an object with ~15 properties. Caching the formatters reference in a local variable at createDebug scope eliminates repeated property lookups.
Rationale
In V8, property lookups on objects with many properties are slower than local variable access. The format scanner runs on every enabled call that has % in the message (50% of bench calls: %s/%d and %O). Each such call does at least one createDebug.formatters lookup. Caching as const fmts = createDebug.formatters at factory scope makes the hot path use a local reference.
Similarly, createDebug.coerce and createDebug.formatArgs.call are per-call lookups that could be cached.
Scope
- src/common.js createDebug(): cache formatters, coerce, formatArgs as local const variables at factory scope
- Update references in the enabled path to use locals
Expected impact
Small. Eliminates 2-4 property lookups per enabled call x 200K calls.
Risks
formatters is an object reference — caching the reference is safe since mutations to the object are still visible through the cached reference. coerce is a function that never changes after setup.
Hypothesis
The format string scanner does createDebug.formatters[char] on every format specifier. createDebug is an object with ~15 properties. Caching the formatters reference in a local variable at createDebug scope eliminates repeated property lookups.
Rationale
In V8, property lookups on objects with many properties are slower than local variable access. The format scanner runs on every enabled call that has % in the message (50% of bench calls: %s/%d and %O). Each such call does at least one createDebug.formatters lookup. Caching as const fmts = createDebug.formatters at factory scope makes the hot path use a local reference.
Similarly, createDebug.coerce and createDebug.formatArgs.call are per-call lookups that could be cached.
Scope
Expected impact
Small. Eliminates 2-4 property lookups per enabled call x 200K calls.
Risks
formatters is an object reference — caching the reference is safe since mutations to the object are still visible through the cached reference. coerce is a function that never changes after setup.