Skip to content

Commit 1212c0d

Browse files
committed
benchmark: add AsyncResource and Call cases
type=AsyncResource calls node::AsyncResource::MakeCallback() and type=Call a plain v8::Function::Call, from the same libuv timer as type=MakeCallback. Call is what the call costs without Node. Signed-off-by: Nigro Simone <nigro.simone@gmail.com>
1 parent 154c15a commit 1212c0d

2 files changed

Lines changed: 33 additions & 6 deletions

File tree

‎benchmark/napi/make_callback/binding.cc‎

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,19 @@ using v8::Local;
1212
using v8::Object;
1313
using v8::Value;
1414

15+
// Same order as the types in index.js.
16+
enum Type { kMakeCallback, kAsyncResource, kCall };
17+
1518
struct State {
1619
uv_timer_t timer;
1720
Isolate* isolate;
1821
int64_t n;
22+
Type type;
1923
Global<Function> fn;
2024
Global<Function> done;
25+
node::AsyncResource* resource = nullptr;
26+
27+
~State() { delete resource; }
2128
};
2229

2330
static void OnTimer(uv_timer_t* handle) {
@@ -30,22 +37,38 @@ static void OnTimer(uv_timer_t* handle) {
3037
Local<Object> recv = context->Global();
3138
for (int64_t i = 0; i < state->n; i++) {
3239
HandleScope inner_scope(isolate);
33-
(void)node::MakeCallback(isolate, recv, fn, 0, nullptr, {0, 0});
40+
switch (state->type) {
41+
case kMakeCallback:
42+
(void)node::MakeCallback(isolate, recv, fn, 0, nullptr, {0, 0});
43+
break;
44+
case kAsyncResource:
45+
(void)state->resource->MakeCallback(fn, 0, nullptr);
46+
break;
47+
case kCall:
48+
(void)fn->Call(context, recv, 0, nullptr);
49+
break;
50+
}
3451
}
3552
Local<Function> done = state->done.Get(isolate);
3653
(void)node::MakeCallback(isolate, recv, done, 0, nullptr, {0, 0});
3754
uv_close(reinterpret_cast<uv_handle_t*>(&state->timer),
3855
[](uv_handle_t* h) { delete static_cast<State*>(h->data); });
3956
}
4057

41-
// run(n, fn, done): calls fn n times from a timer, then calls done.
58+
// run(n, fn, done, type): calls fn n times from a timer, then calls done.
4259
static void Run(const FunctionCallbackInfo<Value>& args) {
4360
Isolate* isolate = args.GetIsolate();
4461
State* state = new State;
4562
state->isolate = isolate;
4663
state->n = args[0]->IntegerValue(isolate->GetCurrentContext()).FromJust();
4764
state->fn.Reset(isolate, args[1].As<Function>());
4865
state->done.Reset(isolate, args[2].As<Function>());
66+
state->type = static_cast<Type>(
67+
args[3]->Int32Value(isolate->GetCurrentContext()).FromJust());
68+
if (state->type == kAsyncResource) {
69+
state->resource =
70+
new node::AsyncResource(isolate, Object::New(isolate), "Benchmark");
71+
}
4972
state->timer.data = state;
5073
uv_timer_init(node::GetCurrentEventLoop(isolate), &state->timer);
5174
uv_timer_start(&state->timer, OnTimer, 0, 0);

‎benchmark/napi/make_callback/index.js‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
const common = require('../../common.js');
44

5-
// The addon calls into JS with node::MakeCallback from a libuv timer, so
6-
// every call opens a top-level callback scope, like an I/O callback does.
5+
// The addon calls into JS from a libuv timer, so every call opens a top-level
6+
// callback scope, like an I/O callback does. type=Call is a plain
7+
// v8::Function::Call, what the call costs without Node.
78

89
let binding;
910
try {
@@ -13,11 +14,14 @@ try {
1314
process.exit(0);
1415
}
1516

17+
const types = ['MakeCallback', 'AsyncResource', 'Call'];
18+
1619
const bench = common.createBenchmark(main, {
20+
type: types,
1721
n: [1e6, 1e7],
1822
});
1923

20-
function main({ n }) {
24+
function main({ type, n }) {
2125
bench.start();
22-
binding.run(n, () => {}, () => bench.end(n));
26+
binding.run(n, () => {}, () => bench.end(n), types.indexOf(type));
2327
}

0 commit comments

Comments
 (0)