| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9c1274a commit b803bca
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -210,17 +210,24 @@ added: v8.5.0 | |||
| 210 | 210 | The [`timeOrigin`][] specifies the high resolution millisecond timestamp at | |
| 211 | 211 | which the current `node` process began, measured in Unix time. | |
| 212 | 212 | ||
| 213 | - ### `performance.timerify(fn)` | ||
| 213 | + ### `performance.timerify(fn[, options])` | ||
| 214 | 214 | <!-- YAML | |
| 215 | 215 | added: v8.5.0 | |
| 216 | 216 | changes: | |
| 217 | + - version: REPLACEME | ||
| 218 | + pr-url: https://github.com/nodejs/node/pull/37475 | ||
| 219 | + description: Added the histogram option. | ||
| 217 | 220 | - version: REPLACEME | |
| 218 | 221 | pr-url: https://github.com/nodejs/node/pull/37136 | |
| 219 | 222 | description: Re-implemented to use pure-JavaScript and the ability | |
| 220 | 223 | to time async functions. | |
| 221 | 224 | --> | |
| 222 | 225 | ||
| 223 | 226 | * `fn` {Function} | |
| 227 | + * `options` {Object} | ||
| 228 | + * `histogram` {RecordableHistogram} A histogram object created using | ||
| 229 | + `perf_hooks.createHistogram()` that will record runtime durations in | ||
| 230 | + nanoseconds. | ||
| 224 | 231 | ||
| 225 | 232 | _This property is an extension by Node.js. It is not available in Web browsers._ | |
| 226 | 233 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -42,6 +42,10 @@ const { | |||
| 42 | 42 | JSTransferable, | |
| 43 | 43 | } = require('internal/worker/js_transferable'); | |
| 44 | 44 | ||
| 45 | + function isHistogram(object) { | ||
| 46 | + return object?.[kHandle] !== undefined; | ||
| 47 | + } | ||
| 48 | + | ||
| 45 | 49 | class Histogram extends JSTransferable { | |
| 46 | 50 | constructor(internal) { | |
| 47 | 51 | super(); | |
@@ -193,6 +197,7 @@ module.exports = { | |||
| 193 | 197 | RecordableHistogram, | |
| 194 | 198 | InternalHistogram, | |
| 195 | 199 | InternalRecordableHistogram, | |
| 200 | + isHistogram, | ||
| 196 | 201 | kDestroy, | |
| 197 | 202 | kHandle, | |
| 198 | 203 | createHistogram, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,7 @@ | |||
| 3 | 3 | const { | |
| 4 | 4 | FunctionPrototypeBind, | |
| 5 | 5 | ObjectDefineProperties, | |
| 6 | + MathCeil, | ||
| 6 | 7 | ReflectApply, | |
| 7 | 8 | ReflectConstruct, | |
| 8 | 9 | Symbol, | |
@@ -13,6 +14,14 @@ const { | |||
| 13 | 14 | now, | |
| 14 | 15 | } = require('internal/perf/perf'); | |
| 15 | 16 | ||
| 17 | + const { | ||
| 18 | + validateObject | ||
| 19 | + } = require('internal/validators'); | ||
| 20 | + | ||
| 21 | + const { | ||
| 22 | + isHistogram | ||
| 23 | + } = require('internal/histogram'); | ||
| 24 | + | ||
| 16 | 25 | const { | |
| 17 | 26 | isConstructor, | |
| 18 | 27 | } = internalBinding('util'); | |
@@ -29,8 +38,10 @@ const { | |||
| 29 | 38 | ||
| 30 | 39 | const kTimerified = Symbol('kTimerified'); | |
| 31 | 40 | ||
| 32 | - function processComplete(name, start, args) { | ||
| 41 | + function processComplete(name, start, args, histogram) { | ||
| 33 | 42 | const duration = now() - start; | |
| 43 | + if (histogram !== undefined) | ||
| 44 | + histogram.record(MathCeil(duration * 1e6)); | ||
| 34 | 45 | const entry = | |
| 35 | 46 | new InternalPerformanceEntry( | |
| 36 | 47 | name, | |
@@ -45,10 +56,23 @@ function processComplete(name, start, args) { | |||
| 45 | 56 | enqueue(entry); | |
| 46 | 57 | } | |
| 47 | 58 | ||
| 48 | - function timerify(fn) { | ||
| 59 | + function timerify(fn, options = {}) { | ||
| 49 | 60 | if (typeof fn !== 'function') | |
| 50 | 61 | throw new ERR_INVALID_ARG_TYPE('fn', 'function', fn); | |
| 51 | 62 | ||
| 63 | + validateObject(options, 'options'); | ||
| 64 | + const { | ||
| 65 | + histogram | ||
| 66 | + } = options; | ||
| 67 | + | ||
| 68 | + if (histogram !== undefined && | ||
| 69 | + (!isHistogram(histogram) || typeof histogram.record !== 'function')) { | ||
| 70 | + throw new ERR_INVALID_ARG_TYPE( | ||
| 71 | + 'options.histogram', | ||
| 72 | + 'RecordableHistogram', | ||
| 73 | + histogram); | ||
| 74 | + } | ||
| 75 | + | ||
| 52 | 76 | if (fn[kTimerified]) return fn[kTimerified]; | |
| 53 | 77 | ||
| 54 | 78 | const constructor = isConstructor(fn); | |
@@ -65,9 +89,10 @@ function timerify(fn) { | |||
| 65 | 89 | result, | |
| 66 | 90 | fn.name, | |
| 67 | 91 | start, | |
| 68 | - args)); | ||
| 92 | + args, | ||
| 93 | + histogram)); | ||
| 69 | 94 | } | |
| 70 | - processComplete(fn.name, start, args); | ||
| 95 | + processComplete(fn.name, start, args, histogram); | ||
| 71 | 96 | return result; | |
| 72 | 97 | } | |
| 73 | 98 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,10 +4,15 @@ const common = require('../common'); | |||
| 4 | 4 | const assert = require('assert'); | |
| 5 | 5 | ||
| 6 | 6 | const { | |
| 7 | + createHistogram, | ||
| 7 | 8 | performance, | |
| 8 | 9 | PerformanceObserver | |
| 9 | 10 | } = require('perf_hooks'); | |
| 10 | 11 | ||
| 12 | + const { | ||
| 13 | + setTimeout: sleep | ||
| 14 | + } = require('timers/promises'); | ||
| 15 | + | ||
| 11 | 16 | { | |
| 12 | 17 | // Intentional non-op. Do not wrap in common.mustCall(); | |
| 13 | 18 | const n = performance.timerify(function noop() {}); | |
@@ -81,3 +86,38 @@ const { | |||
| 81 | 86 | assert.strictEqual(n.length, m.length); | |
| 82 | 87 | assert.strictEqual(n.name, 'timerified m'); | |
| 83 | 88 | } | |
| 89 | + | ||
| 90 | + (async () => { | ||
| 91 | + const histogram = createHistogram(); | ||
| 92 | + const m = (a, b = 1) => {}; | ||
| 93 | + const n = performance.timerify(m, { histogram }); | ||
| 94 | + assert.strictEqual(histogram.max, 0); | ||
| 95 | + for (let i = 0; i < 10; i++) { | ||
| 96 | + n(); | ||
| 97 | + await sleep(10); | ||
| 98 | + } | ||
| 99 | + assert.notStrictEqual(histogram.max, 0); | ||
| 100 | + [1, '', {}, [], false].forEach((histogram) => { | ||
| 101 | + assert.throws(() => performance.timerify(m, { histogram }), { | ||
| 102 | + code: 'ERR_INVALID_ARG_TYPE' | ||
| 103 | + }); | ||
| 104 | + }); | ||
| 105 | + })().then(common.mustCall()); | ||
| 106 | + | ||
| 107 | + (async () => { | ||
| 108 | + const histogram = createHistogram(); | ||
| 109 | + const m = async (a, b = 1) => { | ||
| 110 | + await sleep(10); | ||
| 111 | + }; | ||
| 112 | + const n = performance.timerify(m, { histogram }); | ||
| 113 | + assert.strictEqual(histogram.max, 0); | ||
| 114 | + for (let i = 0; i < 10; i++) { | ||
| 115 | + await n(); | ||
| 116 | + } | ||
| 117 | + assert.notStrictEqual(histogram.max, 0); | ||
| 118 | + [1, '', {}, [], false].forEach((histogram) => { | ||
| 119 | + assert.throws(() => performance.timerify(m, { histogram }), { | ||
| 120 | + code: 'ERR_INVALID_ARG_TYPE' | ||
| 121 | + }); | ||
| 122 | + }); | ||
| 123 | + })().then(common.mustCall()); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments