Skip to content

Commit 5c63e98

Browse files
committed
add napi-sb and wasm to benchmark
1 parent 55a608b commit 5c63e98

File tree

7 files changed

+114
-27
lines changed

7 files changed

+114
-27
lines changed

README.md

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -86,35 +86,53 @@ simple adding function from the test library using the following techniques:
8686

8787
* **`ffi-napi`**: A successor to `node-ffi` compatible with modern versions of
8888
Node.js.
89-
* **`napi-addon`**: A very simple/normal Node.js addon using NAPI in C.
9089
* **`sbffi`**: This library.
90+
* **`napi-addon`**: A very simple/normal Node.js addon using NAPI in C.
91+
* **`napi-addon-sb`**: A NAPI addon using the same shared-buffer technique as
92+
`sbffi`, but with a hard-coded function call, rather than a dynamic/FFI call.
93+
* **`wasm`**: The adding function compiled to WebAssembly.
9194
* **`js`**: Re-implementing the function in plain JavaScript.
9295

9396
Each function will be called 100000 times, in 5 repetitions, timed with
9497
`console.time()`. Here are the results on my machine (2019 Lenovo X1 Extreme,
95-
running Ubuntu):
98+
running Ubuntu, Node v12):
9699

97100
```
98-
ffi-napi: 920.891ms
99-
sbffi: 44.159ms
100-
napi-addon: 7.942ms
101-
js: 2.847ms
102-
ffi-napi: 772.344ms
103-
sbffi: 33.896ms
104-
napi-addon: 4.274ms
105-
js: 0.06ms
106-
ffi-napi: 754.909ms
107-
sbffi: 33.842ms
108-
napi-addon: 4.166ms
109-
js: 0.065ms
110-
ffi-napi: 759.859ms
111-
sbffi: 34.272ms
112-
napi-addon: 4.02ms
113-
js: 0.061ms
114-
ffi-napi: 763.716ms
115-
sbffi: 34.181ms
116-
napi-addon: 4.103ms
117-
js: 0.061ms
101+
ffi-napi: 1103.680ms
102+
sbffi: 39.981ms
103+
napi-addon: 8.214ms
104+
napi-addon-sb: 6.795ms
105+
wasm: 2.802ms
106+
js: 2.644ms
107+
---
108+
ffi-napi: 1128.388ms
109+
sbffi: 97.446ms
110+
napi-addon: 3.631ms
111+
napi-addon-sb: 3.308ms
112+
wasm: 0.918ms
113+
js: 0.045ms
114+
---
115+
ffi-napi: 1419.159ms
116+
sbffi: 29.797ms
117+
napi-addon: 3.946ms
118+
napi-addon-sb: 3.717ms
119+
wasm: 0.871ms
120+
js: 0.090ms
121+
---
122+
ffi-napi: 1285.210ms
123+
sbffi: 73.335ms
124+
napi-addon: 4.618ms
125+
napi-addon-sb: 3.651ms
126+
wasm: 0.930ms
127+
js: 0.096ms
128+
---
129+
ffi-napi: 772.013ms
130+
sbffi: 29.467ms
131+
napi-addon: 3.790ms
132+
napi-addon-sb: 3.352ms
133+
wasm: 0.847ms
134+
js: 0.087ms
135+
---
118136
```
119137

120138
Of course, YMMV.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
"eslint-plugin-promise": "^4.2.1",
4242
"eslint-plugin-standard": "^4.0.1",
4343
"pitesti": "^3.0.0",
44-
"prebuild": "^10.0.0"
44+
"prebuild": "^10.0.0",
45+
"require-wat": "^2.0.2"
4546
},
4647
"binary": {
4748
"napi_versions": [

test/adder/adder.wat

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(module
2+
(func $add (param $a i32) (param $b i32) (result i32)
3+
local.get $a
4+
local.get $b
5+
i32.add
6+
)
7+
(export "add" (func $add))
8+
)

test/bench.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ require('./ensure-built');
22

33
const sbffi = require('../lib/index.js');
44
const ffi = require('ffi-napi');
5-
const { add: napiAdder } = require('./napiaddon');
5+
const { add: napiAdder, sbAdd } = require('./napiaddon');
6+
const { requireWat } = require('require-wat');
67
const path = require('path');
78

89
const libraryPath = path.join(__dirname, 'adder', 'libadder.so');
@@ -15,6 +16,8 @@ const { test_add_uint32_t: ffiAdder } = ffi.Library(libraryPath, {
1516
u32 = 'uint32_t';
1617
const sbffiAdder = sbffi.getNativeFunction(libraryPath, 'test_add_uint32_t', u32, [u32, u32]);
1718

19+
const { add: wasmAdder } = requireWat(path.join(__dirname, '/adder/adder.wat'));
20+
1821
function jsAdder (a, b) {
1922
return a + b;
2023
}
@@ -41,9 +44,23 @@ for (let j = 0; j < REPS; j++) {
4144
}
4245
console.timeEnd('napi-addon');
4346

47+
console.time('napi-addon-sb');
48+
for (let i = 0; i < ITERATIONS; i++) {
49+
sbAdd(i, i);
50+
}
51+
console.timeEnd('napi-addon-sb');
52+
53+
console.time('wasm');
54+
for (let i = 0; i < ITERATIONS; i++) {
55+
wasmAdder(i, i);
56+
}
57+
console.timeEnd('wasm');
58+
4459
console.time('js');
4560
for (let i = 0; i < ITERATIONS; i++) {
4661
jsAdder(i, i);
4762
}
4863
console.timeEnd('js');
64+
65+
console.log('---');
4966
}

test/napiaddon/addon.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,28 @@
22
#define NAPI_VERSION 6
33
#include <assert.h>
44

5+
uint32_t buf[3];
6+
7+
napi_value set_buffer(napi_env env, napi_callback_info info) {
8+
napi_status status;
9+
10+
size_t argc = 1;
11+
napi_value args[1];
12+
status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
13+
assert(status == napi_ok);
14+
15+
size_t len;
16+
status = napi_get_buffer_info(env, args[0], (void **)&buf, &len);
17+
assert(status == napi_ok);
18+
19+
return NULL;
20+
}
21+
22+
napi_value sb_add(napi_env env, napi_callback_info info) {
23+
buf[2] = test_add_uint32_t(buf[0], buf[1]);
24+
return NULL;
25+
}
26+
527
napi_value add(napi_env env, napi_callback_info info) {
628
napi_status status;
729

@@ -31,8 +53,13 @@ napi_value add(napi_env env, napi_callback_info info) {
3153

3254
napi_value Init(napi_env env, napi_value exports) {
3355
napi_status status;
34-
napi_property_descriptor addDescriptor = DECLARE_NAPI_METHOD("add", add);
35-
status = napi_define_properties(env, exports, 1, &addDescriptor);
56+
napi_property_descriptor addDescriptor1 = DECLARE_NAPI_METHOD("add", add);
57+
status = napi_define_properties(env, exports, 1, &addDescriptor1);
58+
napi_property_descriptor addDescriptor2 = DECLARE_NAPI_METHOD("sb_add", sb_add);
59+
status = napi_define_properties(env, exports, 1, &addDescriptor2);
60+
napi_property_descriptor addDescriptor3 = DECLARE_NAPI_METHOD("set_buffer", set_buffer);
61+
status = napi_define_properties(env, exports, 1, &addDescriptor3);
62+
3663
assert(status == napi_ok);
3764
return exports;
3865
}

test/napiaddon/index.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const { sb_add: bindingSbAdd, set_buffer: setBuffer, add } = require('./build/Release/napi.node');
2+
3+
const buf = Buffer.alloc(12);
4+
setBuffer(buf);
5+
6+
const uint32Arr = new Uint32Array(buf.buffer);
7+
8+
function sbAdd (a, b) {
9+
uint32Arr[0] = a;
10+
uint32Arr[1] = b;
11+
bindingSbAdd();
12+
return uint32Arr[2];
13+
}
14+
15+
exports.sbAdd = sbAdd;
16+
exports.add = add;

test/napiaddon/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "napiaddon",
3-
"main": "build/Release/napi.node",
3+
"main": "index.js",
44
"scripts": {
55
"install": "node-gyp rebuild"
66
},

0 commit comments

Comments
 (0)