perf_hooks: implementation of Performance Timing API#14680
perf_hooks: implementation of Performance Timing API#14680jasnell wants to merge 1 commit intonodejs:masterfrom
Conversation
5bc0b95 to
8a059b9
Compare
|
Suggestion: Run |
|
Why deviate from browsers by putting this on |
addaleax
left a comment
There was a problem hiding this comment.
I’ll try to give this a full review later :)
doc/api/process.md
Outdated
There was a problem hiding this comment.
Starting here, these comments have a broken start token
lib/internal/performance.js
Outdated
There was a problem hiding this comment.
There was a problem hiding this comment.
No, it shouldn't. The constructor is not exposed to end users and those tho get there via process.performance.constructor won't hurt anything if they happen to create a new instance.
|
@mscdex ... every time I suggest adding a global, people say no. |
|
@Trott ... I will be :-) |
|
@jasnell That might be the case in general, but for APIs shared with browsers it makes more sense to me IMHO. I can't imagine there would be that many people negatively affected by adding it as a "global" (real or otherwise). |
|
@mscdex ... I don't disagree, but I've run into opposition for |
test/parallel/test-performance.js
Outdated
There was a problem hiding this comment.
The next line makes this assertion unnecessary.
test/parallel/test-performance.js
Outdated
src/node.cc
Outdated
src/node.cc
Outdated
src/node.cc
Outdated
doc/api/process.md
Outdated
There was a problem hiding this comment.
It seems this should go before performance.getEntriesByType(type) alphabetically.
doc/api/process.md
Outdated
There was a problem hiding this comment.
These three references are out of the sorting order.
doc/api/process.md
Outdated
There was a problem hiding this comment.
is a subclass of PerformanceEntry?
doc/api/process.md
Outdated
|
Hooking it on |
TimothyGu
left a comment
There was a problem hiding this comment.
Code review will come later...
doc/api/process.md
Outdated
doc/api/process.md
Outdated
There was a problem hiding this comment.
@domenic Should we link to the published version of the spec or the latest editor's draft?
Also this should reference User Timing and High Resolution Time specs since we also implement those.
There was a problem hiding this comment.
Intentionally started with the first version, will be updating to the latest. The plan is to update incrementally.
doc/api/process.md
Outdated
There was a problem hiding this comment.
In Level 2 there's also a toJSON() method in PerformanceEntry that just serializes the four properties.
doc/api/process.md
Outdated
There was a problem hiding this comment.
High Resolution Time also defines a toJSON() method.
|
A couple of things that still need to be done (in case anyone wants to help ;-) ...)
|
doc/api/process.md
Outdated
There was a problem hiding this comment.
I am not sure, but maybe it is worth documenting the callback's arguments? Is observer the same as the new process.PerformanceObserver() here? And maybe PerformanceObserverEntryList API is also worth documenting?
There was a problem hiding this comment.
Yeah, i'm going to be updating to include those details :-)
doc/api/process.md
Outdated
There was a problem hiding this comment.
It may be my mediocre English, but "instances should be left subscribed to notifications indefinitely" and "Users should disconnect observers as soon as they are no longer needed" seem contradictory. Should it be "should not be left"?
There was a problem hiding this comment.
I just forgot the not in should not
|
Putting this in a new core module makes sense. Currently, the |
e33f50c to
7ddf8a8
Compare
|
Ok, I've refactored this to use a new e.g. const {
performance,
PerformanceObserver
} = require('perf_hooks');
performance.mark('test'); |
doc/api/perf_hooks.md
Outdated
There was a problem hiding this comment.
This is the first occurrence of timeOrigin in this file. I think it is better to provide link here.
doc/api/perf_hooks.md
Outdated
There was a problem hiding this comment.
If the endMark is not passed, shouldn't we throw an error instead of stringifying an undefined and using it?
doc/api/perf_hooks.md
Outdated
doc/api/perf_hooks.md
Outdated
There was a problem hiding this comment.
In few other places in the documentation, high resolution is hyphenated. Perhaps we should unhyphenate them?
doc/api/perf_hooks.md
Outdated
There was a problem hiding this comment.
Did you mean Currently it may be?
doc/api/perf_hooks.md
Outdated
doc/api/perf_hooks.md
Outdated
doc/api/process.md
Outdated
doc/api/perf_hooks.md
Outdated
There was a problem hiding this comment.
If the same name is used, it resets, right? That has to be captured here.
There was a problem hiding this comment.
@domenic ... one point of clarification on this. If I call performance.mark('A') twice, should there be two mark entries in the timeline returned by GetEntries() or only one?
There was a problem hiding this comment.
As far as I can tell from skimming https://w3c.github.io/user-timing/#dom-performance-mark it creates two entries. Maybe @igrigorik can confirm.
src/node_perf.h
Outdated
There was a problem hiding this comment.
Nit: This Node.js feels redundant
lib/perf_hooks.js
Outdated
There was a problem hiding this comment.
Last time I checked, Array.from was extremely slow. Can we do without?
There was a problem hiding this comment.
the response has to be an array. I'll be looking at this more tho
lib/perf_hooks.js
Outdated
There was a problem hiding this comment.
why are we using a Set? Typically iterating over an array is way faster, and overhead matters here.
There was a problem hiding this comment.
The set is to ensure that items are only added once. I'm looking in to see if we need to keep that requirement.
lib/perf_hooks.js
Outdated
There was a problem hiding this comment.
why setImmediate and not nextTick? Can you add a comment?
There was a problem hiding this comment.
The purpose is to allow multiple items to collect. nextTick fires too quickly for that purpose
lib/perf_hooks.js
Outdated
There was a problem hiding this comment.
I usually prefer to have top-level functions for singletons, as the module is already a singleton, but feel free to ignore.
There was a problem hiding this comment.
do you mean having module.exports = new Performance() instead? The challenge with that is the PerformanceObserver class, which also hangs off module.exports here.
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: #14680
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
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: #14680
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Notable Changes * build: * Snapshots are now re-enabled in V8 #14875 * console: * Implement minimal `console.group()`. #14910 * deps: * upgrade libuv to 1.14.1 #14866 * update nghttp2 to v1.25.0 #14955 * dns: * Add `verbatim` option to dns.lookup(). When true, results from the DNS resolver are passed on as-is, without the reshuffling that Node.js otherwise does that puts IPv4 addresses before IPv6 addresses. #14731 * fs: * add fs.copyFile and fs.copyFileSync which allows for more efficient copying of files. #15034 * inspector: * Enable async stack traces #13870 * module: * Add support for ESM. This is currently behind the `--experimental-modules` flag and requires the .mjs extension. `node --experimental-modules index.mjs` #14369 * napi: * implement promise #14365 * os: * Add support for CIDR notation to the output of the networkInterfaces() method. #14307 * perf_hooks: * 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, as is a Node.js specific flavor of the Frame Timing for measuring event loop duration. #14680 * tls: * multiple PFX in createSecureContext [#14793](#14793) * Added new collaborators: * BridgeAR – Ruben Bridgewater PR-URL: #15308
Notable Changes * build: * Snapshots are now re-enabled in V8 #14875 * console: * Implement minimal `console.group()`. #14910 * deps: * upgrade libuv to 1.14.1 #14866 * update nghttp2 to v1.25.0 #14955 * dns: * Add `verbatim` option to dns.lookup(). When true, results from the DNS resolver are passed on as-is, without the reshuffling that Node.js otherwise does that puts IPv4 addresses before IPv6 addresses. #14731 * fs: * add fs.copyFile and fs.copyFileSync which allows for more efficient copying of files. #15034 * inspector: * Enable async stack traces #13870 * module: * Add support for ESM. This is currently behind the `--experimental-modules` flag and requires the .mjs extension. `node --experimental-modules index.mjs` #14369 * napi: * implement promise #14365 * os: * Add support for CIDR notation to the output of the networkInterfaces() method. #14307 * perf_hooks: * 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, as is a Node.js specific flavor of the Frame Timing for measuring event loop duration. #14680 * tls: * multiple PFX in createSecureContext [#14793](#14793) * Added new collaborators: * BridgeAR – Ruben Bridgewater PR-URL: #15308
Notable Changes * build: * Snapshots are now re-enabled in V8 nodejs#14875 * console: * Implement minimal `console.group()`. nodejs#14910 * deps: * upgrade libuv to 1.14.1 nodejs#14866 * update nghttp2 to v1.25.0 nodejs#14955 * dns: * Add `verbatim` option to dns.lookup(). When true, results from the DNS resolver are passed on as-is, without the reshuffling that Node.js otherwise does that puts IPv4 addresses before IPv6 addresses. nodejs#14731 * fs: * add fs.copyFile and fs.copyFileSync which allows for more efficient copying of files. nodejs#15034 * inspector: * Enable async stack traces nodejs#13870 * module: * Add support for ESM. This is currently behind the `--experimental-modules` flag and requires the .mjs extension. `node --experimental-modules index.mjs` nodejs#14369 * napi: * implement promise nodejs#14365 * os: * Add support for CIDR notation to the output of the networkInterfaces() method. nodejs#14307 * perf_hooks: * 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, as is a Node.js specific flavor of the Frame Timing for measuring event loop duration. nodejs#14680 * tls: * multiple PFX in createSecureContext [nodejs#14793](nodejs#14793) * Added new collaborators: * BridgeAR – Ruben Bridgewater PR-URL: nodejs#15308
| `PerformanceNodeTiming` class. If the named `endMark` does not exist, an | ||
| error will be thrown. | ||
|
|
||
| ### performance.nodeFrame |
There was a problem hiding this comment.
@jasnell I'm not finding this property on the performance object, and I can't find any sign of a PerformanceFrame or a PerformanceNodeFrame classes anywhere other than the docs. Did this not get implemented because it depends on libuv/libuv#1489, or is there something else I am missing?
There was a problem hiding this comment.
That should have been removed. I may have forgotten to do so. Yes, the libuv pr needs to land before that can return
There was a problem hiding this comment.
That should have been removed. I may have forgotten to do so. Yes, the libuv pr needs to land before that can return
The node frame (aka loop) timing API did not land, it depends on libuv/libuv#1489 which is still a WIP. See: nodejs#14680 (comment)
The node frame (aka loop) timing API did not land, it depends on libuv/libuv#1489 which is still a WIP. See: #14680 (comment) PR-URL: #15641 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
The node frame (aka loop) timing API did not land, it depends on libuv/libuv#1489 which is still a WIP. See: #14680 (comment) PR-URL: #15641 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
The node frame (aka loop) timing API did not land, it depends on libuv/libuv#1489 which is still a WIP. See: nodejs/node#14680 (comment) PR-URL: nodejs/node#15641 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
The node frame (aka loop) timing API did not land, it depends on libuv/libuv#1489 which is still a WIP. See: #14680 (comment) PR-URL: #15641 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
The node frame (aka loop) timing API did not land, it depends on libuv/libuv#1489 which is still a WIP. See: #14680 (comment) PR-URL: #15641 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
The node frame (aka loop) timing API did not land, it depends on libuv/libuv#1489 which is still a WIP. See: #14680 (comment) PR-URL: #15641 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Timothy Gu <timothygu99@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
|
Release team were -1 on landing on v6.x, if you disagree let us know. |
|
|
PR-URL: nodejs#55247 Refs: nodejs#14680 Refs: nodejs#39297 Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
PR-URL: nodejs#55247 Refs: nodejs#14680 Refs: nodejs#39297 Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
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, as is a Node.js specific flavor of the Frame Timing for measuring event loop duration.
The implementation is at the native layer and makes use of uv_hrtime().
This should enable eventual integeration with the Inspector protocol
so that the performance timeline can be viewed in debugging tools.
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.
/cc @mcollina
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)
perf_hooks