mirror of https://github.com/nodejs/node.git
perf_hooks: performance milestone time origin timestamp improvement
PR-URL: https://github.com/nodejs/node/pull/51713 Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br> Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
This commit is contained in:
parent
8e7da60468
commit
f4af4b111c
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const common = require('../common.js');
|
||||
|
||||
const bench = common.createBenchmark(main, {
|
||||
n: [1e6],
|
||||
method: ['timeOrigin', 'toJSON'],
|
||||
});
|
||||
|
||||
function main({ method, n }) {
|
||||
switch (method) {
|
||||
case 'timeOrigin':
|
||||
benchTimeOrigin(n);
|
||||
break;
|
||||
case 'toJSON':
|
||||
benchToJSON(n);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unsupported method ${method}`);
|
||||
}
|
||||
}
|
||||
|
||||
function benchTimeOrigin(n) {
|
||||
const arr = [];
|
||||
for (let i = 0; i < n; ++i) {
|
||||
arr.push(performance.timeOrigin);
|
||||
}
|
||||
|
||||
bench.start();
|
||||
for (let i = 0; i < n; i++) {
|
||||
arr[i] = performance.timeOrigin;
|
||||
}
|
||||
bench.end(n);
|
||||
|
||||
assert.strictEqual(arr.length, n);
|
||||
}
|
||||
|
||||
function benchToJSON(n) {
|
||||
bench.start();
|
||||
for (let i = 0; i < n; i++) {
|
||||
performance.toJSON();
|
||||
}
|
||||
bench.end(n);
|
||||
}
|
|
@ -22,7 +22,7 @@ const {
|
|||
defineEventHandler,
|
||||
} = require('internal/event_target');
|
||||
|
||||
const { now } = require('internal/perf/utils');
|
||||
const { now, getTimeOriginTimestamp } = require('internal/perf/utils');
|
||||
|
||||
const { markResourceTiming } = require('internal/perf/resource_timing');
|
||||
|
||||
|
@ -46,10 +46,6 @@ const { inspect } = require('util');
|
|||
const { validateInternalField } = require('internal/validators');
|
||||
const { convertToInt } = require('internal/webidl');
|
||||
|
||||
const {
|
||||
getTimeOriginTimestamp,
|
||||
} = internalBinding('performance');
|
||||
|
||||
const kPerformanceBrand = Symbol('performance');
|
||||
|
||||
class Performance extends EventTarget {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
const {
|
||||
constants: {
|
||||
NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN,
|
||||
NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN_TIMESTAMP,
|
||||
},
|
||||
milestones,
|
||||
now,
|
||||
|
@ -22,7 +23,12 @@ function getMilestoneTimestamp(milestoneIdx) {
|
|||
return ns / 1e6 - getTimeOrigin();
|
||||
}
|
||||
|
||||
function getTimeOriginTimestamp() {
|
||||
return milestones[NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN_TIMESTAMP] / 1e3;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
now,
|
||||
getMilestoneTimestamp,
|
||||
getTimeOriginTimestamp,
|
||||
};
|
||||
|
|
|
@ -880,7 +880,10 @@ Environment::Environment(IsolateData* isolate_data,
|
|||
destroy_async_id_list_.reserve(512);
|
||||
|
||||
performance_state_ = std::make_unique<performance::PerformanceState>(
|
||||
isolate, time_origin_, MAYBE_FIELD_PTR(env_info, performance_state));
|
||||
isolate,
|
||||
time_origin_,
|
||||
time_origin_timestamp_,
|
||||
MAYBE_FIELD_PTR(env_info, performance_state));
|
||||
|
||||
if (*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
|
||||
TRACING_CATEGORY_NODE1(environment)) != 0) {
|
||||
|
@ -1837,7 +1840,7 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
|
|||
immediate_info_.Deserialize(ctx);
|
||||
timeout_info_.Deserialize(ctx);
|
||||
tick_info_.Deserialize(ctx);
|
||||
performance_state_->Deserialize(ctx, time_origin_);
|
||||
performance_state_->Deserialize(ctx, time_origin_, time_origin_timestamp_);
|
||||
exit_info_.Deserialize(ctx);
|
||||
stream_base_state_.Deserialize(ctx);
|
||||
should_abort_on_uncaught_toggle_.Deserialize(ctx);
|
||||
|
|
|
@ -24,7 +24,6 @@ using v8::Integer;
|
|||
using v8::Isolate;
|
||||
using v8::Local;
|
||||
using v8::MaybeLocal;
|
||||
using v8::Number;
|
||||
using v8::Object;
|
||||
using v8::ObjectTemplate;
|
||||
using v8::PropertyAttribute;
|
||||
|
@ -43,6 +42,7 @@ uint64_t performance_v8_start;
|
|||
|
||||
PerformanceState::PerformanceState(Isolate* isolate,
|
||||
uint64_t time_origin,
|
||||
double time_origin_timestamp,
|
||||
const PerformanceState::SerializeInfo* info)
|
||||
: root(isolate,
|
||||
sizeof(performance_state_internal),
|
||||
|
@ -63,7 +63,7 @@ PerformanceState::PerformanceState(Isolate* isolate,
|
|||
// For deserialized performance states, we will do the
|
||||
// initialization in the deserialize callback.
|
||||
ResetMilestones();
|
||||
Initialize(time_origin);
|
||||
Initialize(time_origin, time_origin_timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,23 +86,27 @@ PerformanceState::SerializeInfo PerformanceState::Serialize(
|
|||
return info;
|
||||
}
|
||||
|
||||
void PerformanceState::Initialize(uint64_t time_origin) {
|
||||
// We are only reusing the milestone array to store the time origin, so do
|
||||
// not use the Mark() method. The time origin milestone is not exposed
|
||||
// to user land.
|
||||
void PerformanceState::Initialize(uint64_t time_origin,
|
||||
double time_origin_timestamp) {
|
||||
// We are only reusing the milestone array to store the time origin
|
||||
// and time origin timestamp, so do not use the Mark() method.
|
||||
// The time origin milestone is not exposed to user land.
|
||||
this->milestones[NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN] =
|
||||
static_cast<double>(time_origin);
|
||||
this->milestones[NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN_TIMESTAMP] =
|
||||
time_origin_timestamp;
|
||||
}
|
||||
|
||||
void PerformanceState::Deserialize(v8::Local<v8::Context> context,
|
||||
uint64_t time_origin) {
|
||||
uint64_t time_origin,
|
||||
double time_origin_timestamp) {
|
||||
// Resets the pointers.
|
||||
root.Deserialize(context);
|
||||
milestones.Deserialize(context);
|
||||
observers.Deserialize(context);
|
||||
|
||||
// Re-initialize the time origin i.e. the process start time.
|
||||
Initialize(time_origin);
|
||||
// Re-initialize the time origin and timestamp i.e. the process start time.
|
||||
Initialize(time_origin, time_origin_timestamp);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o,
|
||||
|
@ -254,7 +258,7 @@ void Notify(const FunctionCallbackInfo<Value>& args) {
|
|||
void LoopIdleTime(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
uint64_t idle_time = uv_metrics_idle_time(env->event_loop());
|
||||
args.GetReturnValue().Set(1.0 * idle_time / 1e6);
|
||||
args.GetReturnValue().Set(1.0 * idle_time / NANOS_PER_MILLIS);
|
||||
}
|
||||
|
||||
void CreateELDHistogram(const FunctionCallbackInfo<Value>& args) {
|
||||
|
@ -278,12 +282,6 @@ void CreateELDHistogram(const FunctionCallbackInfo<Value>& args) {
|
|||
args.GetReturnValue().Set(histogram->object());
|
||||
}
|
||||
|
||||
void GetTimeOriginTimeStamp(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
args.GetReturnValue().Set(Number::New(
|
||||
args.GetIsolate(), env->time_origin_timestamp() / MICROS_PER_MILLIS));
|
||||
}
|
||||
|
||||
void MarkBootstrapComplete(const FunctionCallbackInfo<Value>& args) {
|
||||
Realm* realm = Realm::GetCurrent(args);
|
||||
CHECK_EQ(realm->kind(), Realm::Kind::kPrincipal);
|
||||
|
@ -324,7 +322,6 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
|
|||
RemoveGarbageCollectionTracking);
|
||||
SetMethod(isolate, target, "notify", Notify);
|
||||
SetMethod(isolate, target, "loopIdleTime", LoopIdleTime);
|
||||
SetMethod(isolate, target, "getTimeOriginTimestamp", GetTimeOriginTimeStamp);
|
||||
SetMethod(isolate, target, "createELDHistogram", CreateELDHistogram);
|
||||
SetMethod(isolate, target, "markBootstrapComplete", MarkBootstrapComplete);
|
||||
SetFastMethodNoSideEffect(
|
||||
|
@ -391,7 +388,6 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
|||
registry->Register(RemoveGarbageCollectionTracking);
|
||||
registry->Register(Notify);
|
||||
registry->Register(LoopIdleTime);
|
||||
registry->Register(GetTimeOriginTimeStamp);
|
||||
registry->Register(CreateELDHistogram);
|
||||
registry->Register(MarkBootstrapComplete);
|
||||
registry->Register(SlowPerformanceNow);
|
||||
|
|
|
@ -25,6 +25,7 @@ extern const double performance_process_start_timestamp;
|
|||
extern uint64_t performance_v8_start;
|
||||
|
||||
#define NODE_PERFORMANCE_MILESTONES(V) \
|
||||
V(TIME_ORIGIN_TIMESTAMP, "timeOriginTimestamp") \
|
||||
V(TIME_ORIGIN, "timeOrigin") \
|
||||
V(ENVIRONMENT, "environment") \
|
||||
V(NODE_START, "nodeStart") \
|
||||
|
@ -64,10 +65,13 @@ class PerformanceState {
|
|||
|
||||
explicit PerformanceState(v8::Isolate* isolate,
|
||||
uint64_t time_origin,
|
||||
double time_origin_timestamp,
|
||||
const SerializeInfo* info);
|
||||
SerializeInfo Serialize(v8::Local<v8::Context> context,
|
||||
v8::SnapshotCreator* creator);
|
||||
void Deserialize(v8::Local<v8::Context> context, uint64_t time_origin);
|
||||
void Deserialize(v8::Local<v8::Context> context,
|
||||
uint64_t time_origin,
|
||||
double time_origin_timestamp);
|
||||
friend std::ostream& operator<<(std::ostream& o, const SerializeInfo& i);
|
||||
|
||||
AliasedUint8Array root;
|
||||
|
@ -81,7 +85,7 @@ class PerformanceState {
|
|||
uint64_t ts = PERFORMANCE_NOW());
|
||||
|
||||
private:
|
||||
void Initialize(uint64_t time_origin);
|
||||
void Initialize(uint64_t time_origin, double time_origin_timestamp);
|
||||
void ResetMilestones();
|
||||
struct performance_state_internal {
|
||||
// doubles first so that they are always sizeof(double)-aligned
|
||||
|
|
Loading…
Reference in New Issue