mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
perf_hooks: implementation of the perf timing API
An initial implementation of the Performance Timing API for Node.js.
This is the same Performance Timing API implemented by modern browsers
with a number of Node.js specific properties. The User Timing mark()
and measure() APIs are implemented, garbage collection timing, and
node startup milestone timing.
```js
const { performance } = require('perf_hooks');
performance.mark('A');
setTimeout(() => {
performance.mark('B');
performance.measure('A to B', 'A', 'B');
const entry = performance.getEntriesByName('A to B', 'measure')[0];
console.log(entry.duration);
}, 10000);
```
The implementation is at the native layer and makes use of uv_hrtime().
This should enable *eventual* integration with things like Tracing
and Inspection.
The implementation is extensible and should allow us to add new
performance entry types as we go (e.g. for measuring i/o perf,
etc).
Documentation and a test are provided.
PR-URL: https://github.com/nodejs/node/pull/14680
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
1 parent
e007f66ae2
commit
67269fd7f3
21 files changed
+2381
-8
No files matched your search
@@ -0,0 +1,93 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
|
||||
const {
|
||||
performance,
|
||||
PerformanceObserver
|
||||
} = require('perf_hooks');
|
||||
|
||||
{
|
||||
// Intentional non-op. Do not wrap in common.mustCall();
|
||||
const n = performance.timerify(() => {});
|
||||
n();
|
||||
const entries = performance.getEntriesByType('function');
|
||||
assert.strictEqual(entries.length, 0);
|
||||
|
||||
const obs = new PerformanceObserver(common.mustCall((list) => {
|
||||
const entries = list.getEntries();
|
||||
const entry = entries[0];
|
||||
assert(entry);
|
||||
assert.strictEqual(entry.name, 'performance.timerify');
|
||||
assert.strictEqual(entry.entryType, 'function');
|
||||
assert.strictEqual(typeof entry.duration, 'number');
|
||||
assert.strictEqual(typeof entry.startTime, 'number');
|
||||
obs.disconnect();
|
||||
performance.clearFunctions();
|
||||
}));
|
||||
obs.observe({ entryTypes: ['function'] });
|
||||
n();
|
||||
}
|
||||
|
||||
{
|
||||
// If the error throws, the error should just be bubbled up and the
|
||||
// performance timeline entry will not be reported.
|
||||
const obs = new PerformanceObserver(common.mustNotCall());
|
||||
obs.observe({ entryTypes: ['function'] });
|
||||
const n = performance.timerify(() => {
|
||||
throw new Error('test');
|
||||
});
|
||||
assert.throws(() => n(), /^Error: test$/);
|
||||
const entries = performance.getEntriesByType('function');
|
||||
assert.strictEqual(entries.length, 0);
|
||||
obs.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
class N {}
|
||||
const n = performance.timerify(N);
|
||||
new n();
|
||||
const entries = performance.getEntriesByType('function');
|
||||
assert.strictEqual(entries.length, 0);
|
||||
|
||||
const obs = new PerformanceObserver(common.mustCall((list) => {
|
||||
const entries = list.getEntries();
|
||||
const entry = entries[0];
|
||||
assert.strictEqual(entry[0], 1);
|
||||
assert.strictEqual(entry[1], 'abc');
|
||||
assert(entry);
|
||||
assert.strictEqual(entry.name, 'N');
|
||||
assert.strictEqual(entry.entryType, 'function');
|
||||
assert.strictEqual(typeof entry.duration, 'number');
|
||||
assert.strictEqual(typeof entry.startTime, 'number');
|
||||
obs.disconnect();
|
||||
performance.clearFunctions();
|
||||
}));
|
||||
obs.observe({ entryTypes: ['function'] });
|
||||
|
||||
new n(1, 'abc');
|
||||
}
|
||||
|
||||
{
|
||||
[1, {}, [], null, undefined, Infinity].forEach((i) => {
|
||||
assert.throws(() => performance.timerify(i),
|
||||
common.expectsError({
|
||||
code: 'ERR_INVALID_ARG_TYPE',
|
||||
type: TypeError,
|
||||
message: 'The "fn" argument must be of type Function'
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
// Function can only be wrapped once, also check length and name
|
||||
{
|
||||
const m = (a, b = 1) => {};
|
||||
const n = performance.timerify(m);
|
||||
const o = performance.timerify(m);
|
||||
const p = performance.timerify(n);
|
||||
assert.strictEqual(n, o);
|
||||
assert.strictEqual(n, p);
|
||||
assert.strictEqual(n.length, m.length);
|
||||
assert.strictEqual(n.name, 'timerified m');
|
||||
}
|
||||
Reference in new issue
Block a user