diff options
author | James M Snell <jasnell@gmail.com> | 2019-01-07 11:36:35 -0800 |
---|---|---|
committer | jasnell <jasnell@gmail.com> | 2019-02-08 09:20:18 -0800 |
commit | bcdd228f90b3e9e428b584814e7d52627616456a (patch) | |
tree | eed1b405a1fd7e2f78bbf10e82d65c57d2c29105 /lib | |
parent | 679c23f2ae1e62443f8d90e653824007ce174139 (diff) | |
download | android-node-v8-bcdd228f90b3e9e428b584814e7d52627616456a.tar.gz android-node-v8-bcdd228f90b3e9e428b584814e7d52627616456a.tar.bz2 android-node-v8-bcdd228f90b3e9e428b584814e7d52627616456a.zip |
perf_hooks: implement histogram based api
Add a sampling-based event loop delay monitor.
```js
const { monitorEventLoopDelay } = require('perf_hooks');
const h = monitorEventLoopDelay();
h.enable();
h.disable();
console.log(h.percentiles);
console.log(h.min);
console.log(h.max);
console.log(h.mean);
console.log(h.stddev);
console.log(h.percentile(50));
```
PR-URL: https://github.com/nodejs/node/pull/25378
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/perf_hooks.js | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/lib/perf_hooks.js b/lib/perf_hooks.js index 583ffb56ca..b1d634bf3c 100644 --- a/lib/perf_hooks.js +++ b/lib/perf_hooks.js @@ -1,6 +1,7 @@ 'use strict'; const { + ELDHistogram: _ELDHistogram, PerformanceEntry, mark: _mark, clearMark: _clearMark, @@ -35,6 +36,8 @@ const { AsyncResource } = require('async_hooks'); const L = require('internal/linkedlist'); const kInspect = require('internal/util').customInspectSymbol; +const kHandle = Symbol('handle'); +const kMap = Symbol('map'); const kCallback = Symbol('callback'); const kTypes = Symbol('types'); const kEntries = Symbol('entries'); @@ -545,9 +548,73 @@ function sortedInsert(list, entry) { list.splice(location, 0, entry); } +class ELDHistogram { + constructor(handle) { + this[kHandle] = handle; + this[kMap] = new Map(); + } + + reset() { this[kHandle].reset(); } + enable() { return this[kHandle].enable(); } + disable() { return this[kHandle].disable(); } + + get exceeds() { return this[kHandle].exceeds(); } + get min() { return this[kHandle].min(); } + get max() { return this[kHandle].max(); } + get mean() { return this[kHandle].mean(); } + get stddev() { return this[kHandle].stddev(); } + percentile(percentile) { + if (typeof percentile !== 'number') { + const errors = lazyErrors(); + throw new errors.ERR_INVALID_ARG_TYPE('percentile', 'number', percentile); + } + if (percentile <= 0 || percentile > 100) { + const errors = lazyErrors(); + throw new errors.ERR_INVALID_ARG_VALUE.RangeError('percentile', + percentile); + } + return this[kHandle].percentile(percentile); + } + get percentiles() { + this[kMap].clear(); + this[kHandle].percentiles(this[kMap]); + return this[kMap]; + } + + [kInspect]() { + return { + min: this.min, + max: this.max, + mean: this.mean, + stddev: this.stddev, + percentiles: this.percentiles, + exceeds: this.exceeds + }; + } +} + +function monitorEventLoopDelay(options = {}) { + if (typeof options !== 'object' || options === null) { + const errors = lazyErrors(); + throw new errors.ERR_INVALID_ARG_TYPE('options', 'Object', options); + } + const { resolution = 10 } = options; + if (typeof resolution !== 'number') { + const errors = lazyErrors(); + throw new errors.ERR_INVALID_ARG_TYPE('options.resolution', + 'number', resolution); + } + if (resolution <= 0 || !Number.isSafeInteger(resolution)) { + const errors = lazyErrors(); + throw new errors.ERR_INVALID_OPT_VALUE.RangeError('resolution', resolution); + } + return new ELDHistogram(new _ELDHistogram(resolution)); +} + module.exports = { performance, - PerformanceObserver + PerformanceObserver, + monitorEventLoopDelay }; Object.defineProperty(module.exports, 'constants', { |