Skip to content

Commit

Permalink
perf_hooks: reduce overhead of new user timings
Browse files Browse the repository at this point in the history
  • Loading branch information
H4ad committed Oct 1, 2023
1 parent aadfea4 commit 5fd5fad
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 29 deletions.
13 changes: 4 additions & 9 deletions lib/internal/perf/performance_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -135,7 +131,6 @@ function createPerformanceNodeEntry(name, type, start, duration, detail) {
}

module.exports = {
initPerformanceEntry,
createPerformanceEntry,
PerformanceEntry,
isPerformanceEntry,
Expand Down
53 changes: 33 additions & 20 deletions lib/internal/perf/usertiming.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -35,7 +33,6 @@ const {

const { structuredClone } = require('internal/structured_clone');
const {
kEmptyObject,
lazyDOMException,
kEnumerableProperty,
} = require('internal/util');
Expand Down Expand Up @@ -69,27 +66,33 @@ function getMark(name) {
return ts;
}

class PerformanceMark {
constructor(name, options = kEmptyObject) {
if (arguments.length === 0) {
const kEmptyArg = Symbol('kEmptyArg');

class PerformanceMark extends PerformanceEntry {
constructor(name = kEmptyArg, options = undefined) {
if (name === kEmptyArg) {
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 !== undefined) {
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;
// The usage of != is intentional, we want to skip structuredClone
// for both undefined and null
detail = detail != null ?
structuredClone(detail) :
null;
initPerformanceEntry(this, name, 'mark', startTime, 0);

super(kSkipThrow, name, 'mark', startTime, 0);
this[kDetail] = detail;
}

Expand All @@ -108,8 +111,7 @@ class PerformanceMark {
};
}
}
ObjectSetPrototypeOf(PerformanceMark, PerformanceEntry);
ObjectSetPrototypeOf(PerformanceMark.prototype, PerformanceEntry.prototype);

ObjectDefineProperties(PerformanceMark.prototype, {
detail: kEnumerableProperty,
[SymbolToStringTag]: {
Expand All @@ -120,8 +122,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() {
Expand All @@ -139,10 +151,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) {
Expand Down

0 comments on commit 5fd5fad

Please sign in to comment.