benchmark: add n-api function arguments benchmark suite#21555
benchmark: add n-api function arguments benchmark suite#21555kenny-y wants to merge 8 commits intonodejs:masterfrom
Conversation
This benchmark suite is added to measure the performance of n-api function call with various type/number of arguments. The cases in this suite are carefully selected to efficiently show the performance trend.
|
The below charts are generated by this benchmark suite: Generally speaking, it's better to cover more combination of types and numbers of arguments, but from my observation, the trend is the same. So I filtered out most of the combination and selected the cases. |
|
@kenny-y I think it might be better placed under I'm surprised that N-API performs better in some use cases than V8. It seems strange. |
| status = napi_create_string_utf8(env, "reduce", strlen("reduce"), &key); | ||
| assert(status == napi_ok); | ||
| status = napi_get_property(env, args[0], key, &value); | ||
| assert(status == napi_ok); |
There was a problem hiding this comment.
You could combine these into napi_get_named_property(). That will internally create the string for you.
| status = napi_typeof(env, args[0], types); | ||
| assert(status == napi_ok); | ||
|
|
||
| assert(types[0] == napi_object); |
There was a problem hiding this comment.
You should add && argc == 1 into the assertion, to be on par with the V8 version.
| v8::Isolate* isolate = args.GetIsolate(); | ||
|
|
||
| assert(args.Length() == 1 && args[0]->IsObject()); | ||
| if (args.Length() == 1 && args[0]->IsObject()) { |
There was a problem hiding this comment.
I think it might be best to save the result of args.Length() == 1 && args[0]->IsObject() first and then both assert() it and use it as the if-statement condition. For clarity, you could assert(argumentsCorrect && "argument length is 1 and the first argument is an object"), where bool argumentsCorrect = (args.Length() == 1 && args[0]->IsObject());
|
Wait, NM. |
| Local<Value> map = obj->Get(String::NewFromUtf8(isolate, "map")); | ||
| Local<Value> operand = obj->Get(String::NewFromUtf8(isolate, "operand")); | ||
| Local<Value> data = obj->Get(String::NewFromUtf8(isolate, "data")); | ||
| Local<Value> reduce = obj->Get(String::NewFromUtf8(isolate, "reduce")); |
There was a problem hiding this comment.
N-API uses the maybe version of Get() and String::NewFromUtf8() because the others are deprecated, so, these should be changed to
Local<Context> context = isolate->GetCurrentContext();and then, for each property,
MaybeLocal<String> map_string = String::NewFromUtf8(isolate,
"map",
NewStringType::kNormal);
assert(!map_string.IsEmpty());
MaybeLocal<value> maybe_map = obj->Get(context, map_string.ToLocalChecked());
assert(!maybe_map.IsEmpty());
Local<Value> map = maybe_map.ToLocalChecked();|
Yep, there was a PR #21046 moved After the change to |
|
@kenny-y thanks for creating this. I won't have time to take a good look until at least next week but looks like @gabrielschulhof is already commenting :) |
|
|
||
| const getArgs = (type) => { | ||
| return generateArgs(type.split('-')[1]); | ||
| }; |
There was a problem hiding this comment.
You don't need this function if you use multiple parameters (see below).
| ['v8', 'napi'].forEach((type) => { | ||
| benchTypes.push(type + '-' + arg); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
You don't need benchTypes either if you use multiple parameters (see below).
| }); | ||
|
|
||
| const bench = common.createBenchmark(main, { | ||
| type: benchTypes, |
There was a problem hiding this comment.
Instead of benchTypes use argsTypes directly, and add a second parameter
engine: ['v8', 'napi'],| n: [1, 1e1, 1e2, 1e3, 1e4, 1e5], | ||
| }); | ||
|
|
||
| function main({ n, type }) { |
There was a problem hiding this comment.
Make this {n, engine, type}, and then you don't need to concatenate or split the arguments. The benchmark will generate all combinations of the three arguments.
There was a problem hiding this comment.
Good to know. Thanks 👍
|
@kenny-y could you please also resolve the warnings? |
|
@mhdawson Thanks. My original purpose to create this benchmark was to find optimization opportunities, like the previous one #21072, but none had been identified yet... @gabrielschulhof helped me a lot on the previous one, as well as this PR 👍 👍 👍 |
| assert(status == napi_ok); \ | ||
| status = napi_set_named_property(env, exports, name, func ## _v); \ | ||
| assert(status == napi_ok); \ | ||
| } while (0); |
There was a problem hiding this comment.
nit: The trailing backslashes must be aligned to the column of the outermost trailing backslash.
|
|
||
| #define EXPORT_FUNC(name, func) \ | ||
| do { \ | ||
| napi_value func ## _v; \ |
There was a problem hiding this comment.
Actually, you can safely declare
napi_status status;
napi_value js_func;here and pass js_func to napi_create_function() and napi_set_named_property() because the do { ... } while (0) scope protects them, and then each invocation of the macro is self-contained. Then there's no need to func ## _v, nor to assume that napi_status status is declared outside the macro.
There was a problem hiding this comment.
Oh, and please pass exports into the macro as a parameter, and put brackets around env, exports, and func when you use them inside the macro.
| NULL, \ | ||
| &js_func); \ | ||
| assert(status == napi_ok); \ | ||
| status = napi_set_named_property((env), \ |
There was a problem hiding this comment.
nit: Align arguments as with the previous call.
|
Since @kfarnung beat me to it I'm happy to leave it at that :) |
|
Landed in 3314b3a. |
This benchmark suite is added to measure the performance of n-api function call with various type/number of arguments. The cases in this suite are carefully selected to efficiently show the performance trend. PR-URL: #21555 Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: Kyle Farnung <kfarnung@microsoft.com>
This benchmark suite is added to measure the performance of n-api function call with various type/number of arguments. The cases in this suite are carefully selected to efficiently show the performance trend. PR-URL: #21555 Reviewed-By: Gabriel Schulhof <gabriel.schulhof@intel.com> Reviewed-By: Kyle Farnung <kfarnung@microsoft.com>










This benchmark suite is added to measure the performance of n-api
function call with various type/number of arguments. The cases in
this suite are carefully selected to efficiently show the performance
trend.
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passes