1// Show the difference between calling a V8 binding C++ function
2// relative to a comparable N-API C++ function,
3// in various types/numbers of arguments.
4// Reports n of calls per second.
5'use strict';
6
7const common = require('../../common.js');
8
9let v8;
10let napi;
11
12try {
13  v8 = require(`./build/${common.buildType}/binding`);
14} catch {
15  console.error(`${__filename}: V8 Binding failed to load`);
16  process.exit(0);
17}
18
19try {
20  napi = require(`./build/${common.buildType}/napi_binding`);
21} catch {
22  console.error(`${__filename}: NAPI-Binding failed to load`);
23  process.exit(0);
24}
25
26const argsTypes = ['String', 'Number', 'Object', 'Array', 'Typedarray',
27                   '10Numbers', '100Numbers', '1000Numbers'];
28
29const generateArgs = (argType) => {
30  let args = [];
31
32  if (argType === 'String') {
33    args.push('The quick brown fox jumps over the lazy dog');
34  } else if (argType === 'LongString') {
35    args.push(Buffer.alloc(32768, '42').toString());
36  } else if (argType === 'Number') {
37    args.push(Math.floor(314158964 * Math.random()));
38  } else if (argType === 'Object') {
39    args.push({
40      map: 'add',
41      operand: 10,
42      data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
43      reduce: 'add',
44    });
45  } else if (argType === 'Array') {
46    const arr = [];
47    for (let i = 0; i < 50; ++i) {
48      arr.push(Math.random() * 10e9);
49    }
50    args.push(arr);
51  } else if (argType === 'Typedarray') {
52    const arr = new Uint32Array(1000);
53    for (let i = 0; i < 1000; ++i) {
54      arr[i] = Math.random() * 4294967296;
55    }
56    args.push(arr);
57  } else if (argType === '10Numbers') {
58    args.push(10);
59    for (let i = 0; i < 9; ++i) {
60      args = [...args, ...generateArgs('Number')];
61    }
62  } else if (argType === '100Numbers') {
63    args.push(100);
64    for (let i = 0; i < 99; ++i) {
65      args = [...args, ...generateArgs('Number')];
66    }
67  } else if (argType === '1000Numbers') {
68    args.push(1000);
69    for (let i = 0; i < 999; ++i) {
70      args = [...args, ...generateArgs('Number')];
71    }
72  }
73
74  return args;
75};
76
77const bench = common.createBenchmark(main, {
78  type: argsTypes,
79  engine: ['v8', 'napi'],
80  n: [1, 1e1, 1e2, 1e3, 1e4, 1e5],
81});
82
83function main({ n, engine, type }) {
84  const bindings = engine === 'v8' ? v8 : napi;
85  const methodName = 'callWith' + type;
86  const fn = bindings[methodName];
87
88  if (fn) {
89    const args = generateArgs(type);
90
91    bench.start();
92    for (let i = 0; i < n; i++) {
93      fn.apply(null, args);
94    }
95    bench.end(n);
96  }
97}
98