Skip to content

Commit c4faa39

Browse files
jasnelldanielleadams
authored andcommitted
perf_hooks: introduce createHistogram
Adds a new `perf_hooks.createHistogram()` API for creating histogram instances that allow user recording. Makes Histogram instances cloneable via MessagePort. This allows, for instance, an event loop delay monitor to be running on the main thread while the histogram data can be monitored actively from a worker thread. Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: #37155 Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 85b1476 commit c4faa39

15 files changed

+784
-323
lines changed

doc/api/perf_hooks.md

+78-36
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,22 @@ performance.mark('test');
653653
performance.mark('meow');
654654
```
655655

656+
## `perf_hooks.createHistogram([options])`
657+
<!-- YAML
658+
added: REPLACEME
659+
-->
660+
661+
* `options` {Object}
662+
* `min` {number|bigint} The minimum recordable value. Must be an integer
663+
value greater than 0. **Defaults**: `1`.
664+
* `max` {number|bigint} The maximum recordable value. Must be an integer
665+
value greater than `min`. **Defaults**: `Number.MAX_SAFE_INTEGER`.
666+
* `figures` {number} The number of accuracy digits. Must be a number between
667+
`1` and `5`. **Defaults**: `3`.
668+
* Returns {RecordableHistogram}
669+
670+
Returns a {RecordableHistogram}.
671+
656672
## `perf_hooks.monitorEventLoopDelay([options])`
657673
<!-- YAML
658674
added: v11.10.0
@@ -661,12 +677,12 @@ added: v11.10.0
661677
* `options` {Object}
662678
* `resolution` {number} The sampling rate in milliseconds. Must be greater
663679
than zero. **Default:** `10`.
664-
* Returns: {Histogram}
680+
* Returns: {IntervalHistogram}
665681

666682
_This property is an extension by Node.js. It is not available in Web browsers._
667683

668-
Creates a `Histogram` object that samples and reports the event loop delay
669-
over time. The delays will be reported in nanoseconds.
684+
Creates an `IntervalHistogram` object that samples and reports the event loop
685+
delay over time. The delays will be reported in nanoseconds.
670686

671687
Using a timer to detect approximate event loop delay works because the
672688
execution of timers is tied specifically to the lifecycle of the libuv
@@ -689,36 +705,12 @@ console.log(h.percentile(50));
689705
console.log(h.percentile(99));
690706
```
691707

692-
### Class: `Histogram`
693-
<!-- YAML
694-
added: v11.10.0
695-
-->
696-
Tracks the event loop delay at a given sampling rate. The constructor of
697-
this class not exposed to users.
698-
699-
_This property is an extension by Node.js. It is not available in Web browsers._
700-
701-
#### `histogram.disable()`
702-
<!-- YAML
703-
added: v11.10.0
704-
-->
705-
706-
* Returns: {boolean}
707-
708-
Disables the event loop delay sample timer. Returns `true` if the timer was
709-
stopped, `false` if it was already stopped.
710-
711-
#### `histogram.enable()`
708+
## Class: `Histogram`
712709
<!-- YAML
713710
added: v11.10.0
714711
-->
715712

716-
* Returns: {boolean}
717-
718-
Enables the event loop delay sample timer. Returns `true` if the timer was
719-
started, `false` if it was already started.
720-
721-
#### `histogram.exceeds`
713+
### `histogram.exceeds`
722714
<!-- YAML
723715
added: v11.10.0
724716
-->
@@ -728,7 +720,7 @@ added: v11.10.0
728720
The number of times the event loop delay exceeded the maximum 1 hour event
729721
loop delay threshold.
730722

731-
#### `histogram.max`
723+
### `histogram.max`
732724
<!-- YAML
733725
added: v11.10.0
734726
-->
@@ -737,7 +729,7 @@ added: v11.10.0
737729

738730
The maximum recorded event loop delay.
739731

740-
#### `histogram.mean`
732+
### `histogram.mean`
741733
<!-- YAML
742734
added: v11.10.0
743735
-->
@@ -746,7 +738,7 @@ added: v11.10.0
746738

747739
The mean of the recorded event loop delays.
748740

749-
#### `histogram.min`
741+
### `histogram.min`
750742
<!-- YAML
751743
added: v11.10.0
752744
-->
@@ -755,7 +747,7 @@ added: v11.10.0
755747

756748
The minimum recorded event loop delay.
757749

758-
#### `histogram.percentile(percentile)`
750+
### `histogram.percentile(percentile)`
759751
<!-- YAML
760752
added: v11.10.0
761753
-->
@@ -765,7 +757,7 @@ added: v11.10.0
765757

766758
Returns the value at the given percentile.
767759

768-
#### `histogram.percentiles`
760+
### `histogram.percentiles`
769761
<!-- YAML
770762
added: v11.10.0
771763
-->
@@ -774,14 +766,14 @@ added: v11.10.0
774766

775767
Returns a `Map` object detailing the accumulated percentile distribution.
776768

777-
#### `histogram.reset()`
769+
### `histogram.reset()`
778770
<!-- YAML
779771
added: v11.10.0
780772
-->
781773

782774
Resets the collected histogram data.
783775

784-
#### `histogram.stddev`
776+
### `histogram.stddev`
785777
<!-- YAML
786778
added: v11.10.0
787779
-->
@@ -790,6 +782,56 @@ added: v11.10.0
790782

791783
The standard deviation of the recorded event loop delays.
792784

785+
## Class: `IntervalHistogram extends Histogram`
786+
787+
A `Histogram` that is periodically updated on a given interval.
788+
789+
### `histogram.disable()`
790+
<!-- YAML
791+
added: v11.10.0
792+
-->
793+
794+
* Returns: {boolean}
795+
796+
Disables the update interval timer. Returns `true` if the timer was
797+
stopped, `false` if it was already stopped.
798+
799+
### `histogram.enable()`
800+
<!-- YAML
801+
added: v11.10.0
802+
-->
803+
804+
* Returns: {boolean}
805+
806+
Enables the update interval timer. Returns `true` if the timer was
807+
started, `false` if it was already started.
808+
809+
### Cloning an `IntervalHistogram`
810+
811+
{IntervalHistogram} instances can be cloned via {MessagePort}. On the receiving
812+
end, the histogram is cloned as a plain {Histogram} object that does not
813+
implement the `enable()` and `disable()` methods.
814+
815+
## Class: `RecordableHistogram extends Histogram`
816+
<!-- YAML
817+
added: REPLACEME
818+
-->
819+
820+
### `histogram.record(val)`
821+
<!-- YAML
822+
added: REPLACEME
823+
-->
824+
825+
* `val` {number|bigint} The amount to record in the histogram.
826+
827+
### `histogram.recordDelta()`
828+
<!-- YAML
829+
added: REPLACEME
830+
-->
831+
832+
Calculates the amount of time (in nanoseconds) that has passed since the
833+
previous call to `recordDelta()` and records that amount in the histogram.
834+
793835
## Examples
794836

795837
### Measuring the duration of async operations

doc/api/worker_threads.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,9 @@ are part of the channel.
474474
<!-- YAML
475475
added: v10.5.0
476476
changes:
477+
- version: REPLACEME
478+
pr-url: https://github.com/nodejs/node/pull/37155
479+
description: Add 'Histogram' types to the list of cloneable types.
477480
- version: v15.6.0
478481
pr-url: https://github.com/nodejs/node/pull/36804
479482
description: Added `X509Certificate` to the list of cloneable types.
@@ -507,8 +510,13 @@ In particular, the significant differences to `JSON` are:
507510
* `value` may contain typed arrays, both using `ArrayBuffer`s
508511
and `SharedArrayBuffer`s.
509512
* `value` may contain [`WebAssembly.Module`][] instances.
510-
* `value` may not contain native (C++-backed) objects other than {MessagePort}s,
511-
{FileHandle}s, {KeyObject}s, {CryptoKey}s, and {X509Certificate}s.
513+
* `value` may not contain native (C++-backed) objects other than:
514+
* {CryptoKey}s,
515+
* {FileHandle}s,
516+
* {Histogram}s,
517+
* {KeyObject}s,
518+
* {MessagePort}s,
519+
* {X509Certificate}s.
512520

513521
```js
514522
const { MessageChannel } = require('worker_threads');

0 commit comments

Comments
 (0)