diff options
author | James M Snell <jasnell@gmail.com> | 2017-08-07 15:53:24 -0700 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2017-08-23 16:00:09 -0700 |
commit | 67269fd7f33279699b1ae71225f3d738518c844c (patch) | |
tree | 22f6a615c02ccb93c69355d101db87f36f08cf06 /test/parallel/test-performance-function.js | |
parent | e007f66ae211192f385dc253bfa19a84e7fc649a (diff) | |
download | android-node-v8-67269fd7f33279699b1ae71225f3d738518c844c.tar.gz android-node-v8-67269fd7f33279699b1ae71225f3d738518c844c.tar.bz2 android-node-v8-67269fd7f33279699b1ae71225f3d738518c844c.zip |
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>
Diffstat (limited to 'test/parallel/test-performance-function.js')
-rw-r--r-- | test/parallel/test-performance-function.js | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/test/parallel/test-performance-function.js b/test/parallel/test-performance-function.js new file mode 100644 index 0000000000..8dd4d3004b --- /dev/null +++ b/test/parallel/test-performance-function.js @@ -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'); +} |