Skip to content

Commit

Permalink
perf_hooks: implement performance.now() with fast API calls
Browse files Browse the repository at this point in the history
PR-URL: #50492
Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Bryan English <bryan@bryanenglish.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
  • Loading branch information
joyeecheung authored and UlisesGascon committed Dec 19, 2023
1 parent be54a22 commit a7d8f6b
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 6 deletions.
23 changes: 23 additions & 0 deletions benchmark/perf_hooks/now.js
@@ -0,0 +1,23 @@
'use strict';

const assert = require('assert');
const common = require('../common.js');

const bench = common.createBenchmark(main, {
n: [1e6],
});

function main({ n }) {
const arr = [];
for (let i = 0; i < n; ++i) {
arr.push(performance.now());
}

bench.start();
for (let i = 0; i < n; i++) {
arr[i] = performance.now();
}
bench.end(n);

assert.strictEqual(arr.length, n);
}
7 changes: 1 addition & 6 deletions lib/internal/perf/utils.js
Expand Up @@ -5,6 +5,7 @@ const {
NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN,
},
milestones,
now,
} = internalBinding('performance');

function getTimeOrigin() {
Expand All @@ -13,12 +14,6 @@ function getTimeOrigin() {
return milestones[NODE_PERFORMANCE_MILESTONE_TIME_ORIGIN] / 1e6;
}

// Returns the time relative to the process start time in milliseconds.
function now() {
const hr = process.hrtime();
return (hr[0] * 1000 + hr[1] / 1e6) - getTimeOrigin();
}

// Returns the milestone relative to the process start time in milliseconds.
function getMilestoneTimestamp(milestoneIdx) {
const ns = milestones[milestoneIdx];
Expand Down
3 changes: 3 additions & 0 deletions src/node_external_reference.h
Expand Up @@ -15,6 +15,8 @@ using CFunctionCallbackWithOneByteString =
using CFunctionCallback = void (*)(v8::Local<v8::Value> receiver);
using CFunctionCallbackReturnDouble =
double (*)(v8::Local<v8::Object> receiver);
using CFunctionCallbackValueReturnDouble =
double (*)(v8::Local<v8::Value> receiver);
using CFunctionCallbackWithInt64 = void (*)(v8::Local<v8::Object> receiver,
int64_t);
using CFunctionCallbackWithBool = void (*)(v8::Local<v8::Object> receiver,
Expand All @@ -38,6 +40,7 @@ class ExternalReferenceRegistry {
V(CFunctionCallback) \
V(CFunctionCallbackWithOneByteString) \
V(CFunctionCallbackReturnDouble) \
V(CFunctionCallbackValueReturnDouble) \
V(CFunctionCallbackWithInt64) \
V(CFunctionCallbackWithBool) \
V(CFunctionCallbackWithString) \
Expand Down
21 changes: 21 additions & 0 deletions src/node_perf.cc
Expand Up @@ -291,6 +291,22 @@ void MarkBootstrapComplete(const FunctionCallbackInfo<Value>& args) {
performance::NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
}

static double PerformanceNowImpl() {
return static_cast<double>(uv_hrtime() - performance_process_start) /
NANOS_PER_MILLIS;
}

static double FastPerformanceNow(v8::Local<v8::Value> receiver) {
return PerformanceNowImpl();
}

static void SlowPerformanceNow(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(PerformanceNowImpl());
}

static v8::CFunction fast_performance_now(
v8::CFunction::Make(FastPerformanceNow));

static void CreatePerIsolateProperties(IsolateData* isolate_data,
Local<ObjectTemplate> target) {
Isolate* isolate = isolate_data->isolate();
Expand All @@ -311,6 +327,8 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
SetMethod(isolate, target, "getTimeOriginTimestamp", GetTimeOriginTimeStamp);
SetMethod(isolate, target, "createELDHistogram", CreateELDHistogram);
SetMethod(isolate, target, "markBootstrapComplete", MarkBootstrapComplete);
SetFastMethodNoSideEffect(
isolate, target, "now", SlowPerformanceNow, &fast_performance_now);
}

void CreatePerContextProperties(Local<Object> target,
Expand Down Expand Up @@ -376,6 +394,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(GetTimeOriginTimeStamp);
registry->Register(CreateELDHistogram);
registry->Register(MarkBootstrapComplete);
registry->Register(SlowPerformanceNow);
registry->Register(FastPerformanceNow);
registry->Register(fast_performance_now.GetTypeInfo());
HistogramBase::RegisterExternalReferences(registry);
IntervalHistogram::RegisterExternalReferences(registry);
}
Expand Down

0 comments on commit a7d8f6b

Please sign in to comment.