diff options
author | James M Snell <jasnell@gmail.com> | 2017-08-08 01:53:24 +0300 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2017-08-24 02:00:09 +0300 |
commit | 67269fd7f33279699b1ae71225f3d738518c844c (patch) | |
tree | 22f6a615c02ccb93c69355d101db87f36f08cf06 /src/node_perf_common.h | |
parent | e007f66ae211192f385dc253bfa19a84e7fc649a (diff) |
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 'src/node_perf_common.h')
-rw-r--r-- | src/node_perf_common.h | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/node_perf_common.h b/src/node_perf_common.h new file mode 100644 index 00000000000..30efcb6134b --- /dev/null +++ b/src/node_perf_common.h @@ -0,0 +1,71 @@ +#ifndef SRC_NODE_PERF_COMMON_H_ +#define SRC_NODE_PERF_COMMON_H_ + +#include "node.h" +#include "v8.h" + +#include <map> +#include <string> + +namespace node { +namespace performance { + +#define PERFORMANCE_NOW() uv_hrtime() + +// These occur before the environment is created. Cache them +// here and add them to the milestones when the env is init'd. +extern uint64_t performance_node_start; +extern uint64_t performance_v8_start; + +#define NODE_PERFORMANCE_MILESTONES(V) \ + V(ENVIRONMENT, "environment") \ + V(NODE_START, "nodeStart") \ + V(V8_START, "v8Start") \ + V(LOOP_START, "loopStart") \ + V(LOOP_EXIT, "loopExit") \ + V(BOOTSTRAP_COMPLETE, "bootstrapComplete") \ + V(THIRD_PARTY_MAIN_START, "thirdPartyMainStart") \ + V(THIRD_PARTY_MAIN_END, "thirdPartyMainEnd") \ + V(CLUSTER_SETUP_START, "clusterSetupStart") \ + V(CLUSTER_SETUP_END, "clusterSetupEnd") \ + V(MODULE_LOAD_START, "moduleLoadStart") \ + V(MODULE_LOAD_END, "moduleLoadEnd") \ + V(PRELOAD_MODULE_LOAD_START, "preloadModulesLoadStart") \ + V(PRELOAD_MODULE_LOAD_END, "preloadModulesLoadEnd") + +#define NODE_PERFORMANCE_ENTRY_TYPES(V) \ + V(NODE, "node") \ + V(MARK, "mark") \ + V(MEASURE, "measure") \ + V(GC, "gc") \ + V(FUNCTION, "function") + +enum PerformanceMilestone { +#define V(name, _) NODE_PERFORMANCE_MILESTONE_##name, + NODE_PERFORMANCE_MILESTONES(V) +#undef V + NODE_PERFORMANCE_MILESTONE_INVALID +}; + +enum PerformanceEntryType { +#define V(name, _) NODE_PERFORMANCE_ENTRY_TYPE_##name, + NODE_PERFORMANCE_ENTRY_TYPES(V) +#undef V + NODE_PERFORMANCE_ENTRY_TYPE_INVALID +}; + +#define PERFORMANCE_MARK(env, n) \ + do { \ + node::performance::MarkPerformanceMilestone(env, \ + node::performance::NODE_PERFORMANCE_MILESTONE_##n); \ + } while (0); + +struct performance_state { + uint32_t observers[NODE_PERFORMANCE_ENTRY_TYPE_INVALID]; + double milestones[NODE_PERFORMANCE_MILESTONE_INVALID]; +}; + +} // namespace performance +} // namespace node + +#endif // SRC_NODE_PERF_COMMON_H_ |