GeezerVison is showing github.com — ffi: add shared-buffer fast path for numeric and pointer signatures · nodejs/node@528f8b2
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboard +28Lines changed: 28 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common.js'); | | 4 | +const ffi = require('node:ffi'); | | 5 | +const { libraryPath, ensureFixtureLibrary } = require('./common.js'); | | 6 | + | | 7 | +const bench = common.createBenchmark(main, { | | 8 | + n: [1e7], | | 9 | +}, { | | 10 | + flags: ['--experimental-ffi'], | | 11 | +}); | | 12 | + | | 13 | +ensureFixtureLibrary(); | | 14 | + | | 15 | +const { lib, functions } = ffi.dlopen(libraryPath, { | | 16 | + add_f64: { result: 'f64', parameters: ['f64', 'f64'] }, | | 17 | +}); | | 18 | + | | 19 | +const add = functions.add_f64; | | 20 | + | | 21 | +function main({ n }) { | | 22 | + bench.start(); | | 23 | + for (let i = 0; i < n; ++i) | | 24 | + add(1.5, 2.5); | | 25 | + bench.end(n); | | 26 | + | | 27 | + lib.close(); | | 28 | +} |
Collapse file Copy file name to clipboard +28Lines changed: 28 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common.js'); | | 4 | +const ffi = require('node:ffi'); | | 5 | +const { libraryPath, ensureFixtureLibrary } = require('./common.js'); | | 6 | + | | 7 | +const bench = common.createBenchmark(main, { | | 8 | + n: [1e7], | | 9 | +}, { | | 10 | + flags: ['--experimental-ffi'], | | 11 | +}); | | 12 | + | | 13 | +ensureFixtureLibrary(); | | 14 | + | | 15 | +const { lib, functions } = ffi.dlopen(libraryPath, { | | 16 | + add_i32: { result: 'i32', parameters: ['i32', 'i32'] }, | | 17 | +}); | | 18 | + | | 19 | +const add = functions.add_i32; | | 20 | + | | 21 | +function main({ n }) { | | 22 | + bench.start(); | | 23 | + for (let i = 0; i < n; ++i) | | 24 | + add(20, 22); | | 25 | + bench.end(n); | | 26 | + | | 27 | + lib.close(); | | 28 | +} |
Collapse file Copy file name to clipboard +24Lines changed: 24 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common.js'); | | 4 | +const fs = require('node:fs'); | | 5 | +const path = require('node:path'); | | 6 | + | | 7 | +// Cannot use test/ffi/ffi-test-common.js because it requires test/common | | 8 | +// (the test harness module). Construct the path directly. | | 9 | +const libraryPath = path.join(__dirname, '..', '..', 'test', 'ffi', | | 10 | + 'fixture_library', 'build', common.buildType, | | 11 | + process.platform === 'win32' ? 'ffi_test_library.dll' : | | 12 | + process.platform === 'darwin' ? 'ffi_test_library.dylib' : | | 13 | + 'ffi_test_library.so'); | | 14 | + | | 15 | +function ensureFixtureLibrary() { | | 16 | + if (!fs.existsSync(libraryPath)) { | | 17 | + throw new Error( | | 18 | + `Missing FFI fixture library: ${libraryPath}. ` + | | 19 | + 'Build it with `tools/test.py test/ffi/test-ffi-calls.js` first.', | | 20 | + ); | | 21 | + } | | 22 | +} | | 23 | + | | 24 | +module.exports = { libraryPath, ensureFixtureLibrary }; |
Collapse file Copy file name to clipboard +28Lines changed: 28 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common.js'); | | 4 | +const ffi = require('node:ffi'); | | 5 | +const { libraryPath, ensureFixtureLibrary } = require('./common.js'); | | 6 | + | | 7 | +const bench = common.createBenchmark(main, { | | 8 | + n: [1e7], | | 9 | +}, { | | 10 | + flags: ['--experimental-ffi'], | | 11 | +}); | | 12 | + | | 13 | +ensureFixtureLibrary(); | | 14 | + | | 15 | +const { lib, functions } = ffi.dlopen(libraryPath, { | | 16 | + sum_6_i32: { result: 'i32', parameters: ['i32', 'i32', 'i32', 'i32', 'i32', 'i32'] }, | | 17 | +}); | | 18 | + | | 19 | +const fn = functions.sum_6_i32; | | 20 | + | | 21 | +function main({ n }) { | | 22 | + bench.start(); | | 23 | + for (let i = 0; i < n; ++i) | | 24 | + fn(1, 2, 3, 4, 5, 6); | | 25 | + bench.end(n); | | 26 | + | | 27 | + lib.close(); | | 28 | +} |
Collapse file Copy file name to clipboard +28Lines changed: 28 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common.js'); | | 4 | +const ffi = require('node:ffi'); | | 5 | +const { libraryPath, ensureFixtureLibrary } = require('./common.js'); | | 6 | + | | 7 | +const bench = common.createBenchmark(main, { | | 8 | + n: [1e7], | | 9 | +}, { | | 10 | + flags: ['--experimental-ffi'], | | 11 | +}); | | 12 | + | | 13 | +ensureFixtureLibrary(); | | 14 | + | | 15 | +const { lib, functions } = ffi.dlopen(libraryPath, { | | 16 | + pointer_to_usize: { result: 'u64', parameters: ['pointer'] }, | | 17 | +}); | | 18 | + | | 19 | +const fn = functions.pointer_to_usize; | | 20 | + | | 21 | +function main({ n }) { | | 22 | + bench.start(); | | 23 | + for (let i = 0; i < n; ++i) | | 24 | + fn(0xdeadbeefn); | | 25 | + bench.end(n); | | 26 | + | | 27 | + lib.close(); | | 28 | +} |
Collapse file Copy file name to clipboard +33Lines changed: 33 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common.js'); | | 4 | +const ffi = require('node:ffi'); | | 5 | +const { libraryPath, ensureFixtureLibrary } = require('./common.js'); | | 6 | + | | 7 | +const bench = common.createBenchmark(main, { | | 8 | + size: [64, 1024, 16384], | | 9 | + n: [1e6], | | 10 | +}, { | | 11 | + flags: ['--experimental-ffi'], | | 12 | +}); | | 13 | + | | 14 | +ensureFixtureLibrary(); | | 15 | + | | 16 | +const { lib, functions } = ffi.dlopen(libraryPath, { | | 17 | + sum_buffer: { result: 'u64', parameters: ['pointer', 'u64'] }, | | 18 | +}); | | 19 | + | | 20 | +function main({ n, size }) { | | 21 | + const buf = Buffer.alloc(size, 0x42); | | 22 | + const ptr = ffi.getRawPointer(buf); | | 23 | + const len = BigInt(size); | | 24 | + | | 25 | + const sum = functions.sum_buffer; | | 26 | + | | 27 | + bench.start(); | | 28 | + for (let i = 0; i < n; ++i) | | 29 | + sum(ptr, len); | | 30 | + bench.end(n); | | 31 | + | | 32 | + lib.close(); | | 33 | +} |
Collapse file Copy file name to clipboardExpand all lines: lib/ffi.js +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -53,6 +53,8 @@ const { | 53 | 53 | toArrayBuffer, | 54 | 54 | } = internalBinding('ffi'); | 55 | 55 |
| | 56 | +require('internal/ffi-shared-buffer'); | | 57 | + | 56 | 58 | function checkFFIPermission() { | 57 | 59 | if (!permission.isEnabled() || permission.has('ffi')) { | 58 | 60 | return; | |
|