Skip to content

Commit b5e5c42

Browse files
legendecaslouwers
authored andcommitted
node-api: add external buffer creation benchmark
Add a micro benchmark for external buffer creation. PR-URL: nodejs#54877 Refs: nodejs#53804 Refs: nodejs#44111 Reviewed-By: Gabriel Schulhof <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
1 parent 2391ba6 commit b5e5c42

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed

benchmark/napi/buffer/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/

benchmark/napi/buffer/binding.cc

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#include <node_api.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
5+
#define NODE_API_CALL(call) \
6+
do { \
7+
napi_status status = call; \
8+
if (status != napi_ok) { \
9+
fprintf(stderr, #call " failed: %d\n", status); \
10+
abort(); \
11+
} \
12+
} while (0)
13+
14+
#define ABORT_IF_FALSE(condition) \
15+
if (!(condition)) { \
16+
fprintf(stderr, #condition " failed\n"); \
17+
abort(); \
18+
}
19+
20+
static void Finalize(node_api_basic_env env, void* data, void* hint) {
21+
delete[] static_cast<uint8_t*>(data);
22+
}
23+
24+
static napi_value CreateExternalBuffer(napi_env env, napi_callback_info info) {
25+
napi_value argv[2], undefined, start, end;
26+
size_t argc = 2;
27+
int32_t n = 0;
28+
napi_valuetype val_type = napi_undefined;
29+
30+
// Validate params and retrieve start and end function.
31+
NODE_API_CALL(napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
32+
ABORT_IF_FALSE(argc == 2);
33+
NODE_API_CALL(napi_typeof(env, argv[0], &val_type));
34+
ABORT_IF_FALSE(val_type == napi_object);
35+
NODE_API_CALL(napi_typeof(env, argv[1], &val_type));
36+
ABORT_IF_FALSE(val_type == napi_number);
37+
NODE_API_CALL(napi_get_named_property(env, argv[0], "start", &start));
38+
NODE_API_CALL(napi_typeof(env, start, &val_type));
39+
ABORT_IF_FALSE(val_type == napi_function);
40+
NODE_API_CALL(napi_get_named_property(env, argv[0], "end", &end));
41+
NODE_API_CALL(napi_typeof(env, end, &val_type));
42+
ABORT_IF_FALSE(val_type == napi_function);
43+
NODE_API_CALL(napi_get_value_int32(env, argv[1], &n));
44+
45+
NODE_API_CALL(napi_get_undefined(env, &undefined));
46+
47+
constexpr uint32_t kBufferLen = 32;
48+
49+
// Start the benchmark.
50+
napi_call_function(env, argv[0], start, 0, nullptr, nullptr);
51+
52+
for (int32_t idx = 0; idx < n; idx++) {
53+
napi_handle_scope scope;
54+
uint8_t* buffer = new uint8_t[kBufferLen];
55+
napi_value jsbuffer;
56+
NODE_API_CALL(napi_open_handle_scope(env, &scope));
57+
NODE_API_CALL(napi_create_external_buffer(
58+
env, kBufferLen, buffer, Finalize, nullptr, &jsbuffer));
59+
NODE_API_CALL(napi_close_handle_scope(env, scope));
60+
}
61+
62+
// Conclude the benchmark.
63+
napi_value end_argv[] = {argv[1]};
64+
NODE_API_CALL(napi_call_function(env, argv[0], end, 1, end_argv, nullptr));
65+
66+
return undefined;
67+
}
68+
69+
NAPI_MODULE_INIT() {
70+
napi_property_descriptor props[] = {
71+
{"createExternalBuffer",
72+
nullptr,
73+
CreateExternalBuffer,
74+
nullptr,
75+
nullptr,
76+
nullptr,
77+
static_cast<napi_property_attributes>(napi_writable | napi_configurable |
78+
napi_enumerable),
79+
nullptr},
80+
};
81+
82+
NODE_API_CALL(napi_define_properties(
83+
env, exports, sizeof(props) / sizeof(*props), props));
84+
return exports;
85+
}

benchmark/napi/buffer/binding.gyp

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
'targets': [
3+
{
4+
'target_name': 'binding',
5+
'sources': [ 'binding.cc' ],
6+
'defines': [
7+
'NAPI_EXPERIMENTAL'
8+
]
9+
},
10+
{
11+
'target_name': 'binding_node_api_v8',
12+
'sources': [ 'binding.cc' ],
13+
'defines': [
14+
'NAPI_VERSION=8'
15+
]
16+
}
17+
]
18+
}

benchmark/napi/buffer/index.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'use strict';
2+
3+
const common = require('../../common.js');
4+
5+
const bench = common.createBenchmark(main, {
6+
n: [5e6],
7+
addon: ['binding', 'binding_node_api_v8'],
8+
implem: ['createExternalBuffer'],
9+
});
10+
11+
function main({ n, implem, addon }) {
12+
const binding = require(`./build/${common.buildType}/${addon}`);
13+
binding[implem](bench, n);
14+
}

0 commit comments

Comments
 (0)