From 0e507d30acba74c79cd4292aa192eddcd892429a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vinicius=20Louren=C3=A7o?= <12551007+H4ad@users.noreply.github.com> Date: Thu, 5 Oct 2023 07:47:49 -0300 Subject: [PATCH] perf_hooks: reduce overhead of new user timings PR-URL: https://github.com/nodejs/node/pull/49914 Reviewed-By: Yagiz Nizipli Reviewed-By: Benjamin Gruenbaum Reviewed-By: Stephen Belanger --- lib/internal/perf/performance_entry.js | 13 +++---- lib/internal/perf/usertiming.js | 47 +++++++++++++++----------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/lib/internal/perf/performance_entry.js b/lib/internal/perf/performance_entry.js index f6a7520e267c5b..76af221a5d1ae2 100644 --- a/lib/internal/perf/performance_entry.js +++ b/lib/internal/perf/performance_entry.js @@ -42,7 +42,10 @@ class PerformanceEntry { throw new ERR_ILLEGAL_CONSTRUCTOR(); } - initPerformanceEntry(this, name, type, start, duration); + this[kName] = name; + this[kEntryType] = type; + this[kStartTime] = start; + this[kDuration] = duration; } get name() { @@ -94,13 +97,6 @@ ObjectDefineProperties(PerformanceEntry.prototype, { toJSON: kEnumerableProperty, }); -function initPerformanceEntry(entry, name, type, start, duration) { - entry[kName] = name; - entry[kEntryType] = type; - entry[kStartTime] = start; - entry[kDuration] = duration; -} - function createPerformanceEntry(name, type, start, duration) { return new PerformanceEntry(kSkipThrow, name, type, start, duration); } @@ -135,7 +131,6 @@ function createPerformanceNodeEntry(name, type, start, duration, detail) { } module.exports = { - initPerformanceEntry, createPerformanceEntry, PerformanceEntry, isPerformanceEntry, diff --git a/lib/internal/perf/usertiming.js b/lib/internal/perf/usertiming.js index 42c343a632be40..ff417d94700550 100644 --- a/lib/internal/perf/usertiming.js +++ b/lib/internal/perf/usertiming.js @@ -2,16 +2,14 @@ const { ObjectDefineProperties, - ObjectSetPrototypeOf, SafeMap, SafeSet, SafeArrayIterator, Symbol, SymbolToStringTag, - ReflectConstruct, } = primordials; -const { initPerformanceEntry, PerformanceEntry } = require('internal/perf/performance_entry'); +const { PerformanceEntry, kSkipThrow } = require('internal/perf/performance_entry'); const { now } = require('internal/perf/utils'); const { enqueue, bufferUserTiming } = require('internal/perf/observe'); const nodeTiming = require('internal/perf/nodetiming'); @@ -35,7 +33,6 @@ const { const { structuredClone } = require('internal/structured_clone'); const { - kEmptyObject, lazyDOMException, kEnumerableProperty, } = require('internal/util'); @@ -69,27 +66,29 @@ function getMark(name) { return ts; } -class PerformanceMark { - constructor(name, options = kEmptyObject) { +class PerformanceMark extends PerformanceEntry { + constructor(name, options = undefined) { if (arguments.length === 0) { throw new ERR_MISSING_ARGS('name'); } name = `${name}`; - options ??= kEmptyObject; if (nodeTimingReadOnlyAttributes.has(name)) throw new ERR_INVALID_ARG_VALUE('name', name); - validateObject(options, 'options'); - const startTime = options.startTime ?? now(); + if (options != null) { + validateObject(options, 'options'); + } + const startTime = options?.startTime ?? now(); validateNumber(startTime, 'startTime'); if (startTime < 0) throw new ERR_PERFORMANCE_INVALID_TIMESTAMP(startTime); markTimings.set(name, startTime); - let detail = options.detail; + let detail = options?.detail; detail = detail != null ? structuredClone(detail) : null; - initPerformanceEntry(this, name, 'mark', startTime, 0); + + super(kSkipThrow, name, 'mark', startTime, 0); this[kDetail] = detail; } @@ -108,8 +107,7 @@ class PerformanceMark { }; } } -ObjectSetPrototypeOf(PerformanceMark, PerformanceEntry); -ObjectSetPrototypeOf(PerformanceMark.prototype, PerformanceEntry.prototype); + ObjectDefineProperties(PerformanceMark.prototype, { detail: kEnumerableProperty, [SymbolToStringTag]: { @@ -120,8 +118,18 @@ ObjectDefineProperties(PerformanceMark.prototype, { }); class PerformanceMeasure extends PerformanceEntry { - constructor() { - throw new ERR_ILLEGAL_CONSTRUCTOR(); + constructor( + skipThrowSymbol = undefined, + name = undefined, + type = undefined, + start = undefined, + duration = undefined, + ) { + if (skipThrowSymbol !== kSkipThrow) { + throw new ERR_ILLEGAL_CONSTRUCTOR(); + } + + super(skipThrowSymbol, name, type, start, duration); } get detail() { @@ -139,10 +147,11 @@ ObjectDefineProperties(PerformanceMeasure.prototype, { }); function createPerformanceMeasure(name, start, duration, detail) { - return ReflectConstruct(function PerformanceMeasure() { - initPerformanceEntry(this, name, 'measure', start, duration); - this[kDetail] = detail; - }, [], PerformanceMeasure); + const measure = new PerformanceMeasure(kSkipThrow, name, 'measure', start, duration); + + measure[kDetail] = detail; + + return measure; } function mark(name, options) {