aboutsummaryrefslogtreecommitdiff
path: root/bench/snippets/ffi-overhead.mjs
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-09 16:35:06 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-08-09 16:35:06 -0700
commit429abc12781aa6b93417ad6de8a69028900ad33d (patch)
treeb3dd00f04f641dc8ffdfce5586879ffcf8a236d1 /bench/snippets/ffi-overhead.mjs
parent3dca3baaec4babf1521f57d46feff6d7c69229aa (diff)
downloadbun-429abc12781aa6b93417ad6de8a69028900ad33d.tar.gz
bun-429abc12781aa6b93417ad6de8a69028900ad33d.tar.zst
bun-429abc12781aa6b93417ad6de8a69028900ad33d.zip
[bun:ffi] ~30% perf improvement for wrapped functions
Diffstat (limited to 'bench/snippets/ffi-overhead.mjs')
-rw-r--r--bench/snippets/ffi-overhead.mjs465
1 files changed, 465 insertions, 0 deletions
diff --git a/bench/snippets/ffi-overhead.mjs b/bench/snippets/ffi-overhead.mjs
new file mode 100644
index 000000000..dcceef7ba
--- /dev/null
+++ b/bench/snippets/ffi-overhead.mjs
@@ -0,0 +1,465 @@
+import {
+ viewSource,
+ dlopen,
+ CString,
+ ptr,
+ toBuffer,
+ toArrayBuffer,
+ FFIType,
+ callback,
+} from "bun:ffi";
+import { bench, group, run } from "mitata";
+
+const types = {
+ returns_true: {
+ returns: "bool",
+ args: [],
+ },
+ returns_false: {
+ returns: "bool",
+ args: [],
+ },
+ returns_42_char: {
+ returns: "char",
+ args: [],
+ },
+ returns_42_float: {
+ returns: "float",
+ args: [],
+ },
+ returns_42_double: {
+ returns: "double",
+ args: [],
+ },
+ returns_42_uint8_t: {
+ returns: "uint8_t",
+ args: [],
+ },
+ returns_neg_42_int8_t: {
+ returns: "int8_t",
+ args: [],
+ },
+ returns_42_uint16_t: {
+ returns: "uint16_t",
+ args: [],
+ },
+ returns_42_uint32_t: {
+ returns: "uint32_t",
+ args: [],
+ },
+ // // returns_42_uint64_t: {
+ // // returns: "uint64_t",
+ // // args: [],
+ // // },
+ returns_neg_42_int16_t: {
+ returns: "int16_t",
+ args: [],
+ },
+ returns_neg_42_int32_t: {
+ returns: "int32_t",
+ args: [],
+ },
+ // returns_neg_42_int64_t: {
+ // returns: "int64_t",
+ // args: [],
+ // },
+
+ identity_char: {
+ returns: "char",
+ args: ["char"],
+ },
+ identity_float: {
+ returns: "float",
+ args: ["float"],
+ },
+ identity_bool: {
+ returns: "bool",
+ args: ["bool"],
+ },
+ identity_double: {
+ returns: "double",
+ args: ["double"],
+ },
+ identity_int8_t: {
+ returns: "int8_t",
+ args: ["int8_t"],
+ },
+ identity_int16_t: {
+ returns: "int16_t",
+ args: ["int16_t"],
+ },
+ identity_int32_t: {
+ returns: "int32_t",
+ args: ["int32_t"],
+ },
+ // identity_int64_t: {
+ // returns: "int64_t",
+ // args: ["int64_t"],
+ // },
+ identity_uint8_t: {
+ returns: "uint8_t",
+ args: ["uint8_t"],
+ },
+ identity_uint16_t: {
+ returns: "uint16_t",
+ args: ["uint16_t"],
+ },
+ identity_uint32_t: {
+ returns: "uint32_t",
+ args: ["uint32_t"],
+ },
+ // identity_uint64_t: {
+ // returns: "uint64_t",
+ // args: ["uint64_t"],
+ // },
+
+ add_char: {
+ returns: "char",
+ args: ["char", "char"],
+ },
+ add_float: {
+ returns: "float",
+ args: ["float", "float"],
+ },
+ add_double: {
+ returns: "double",
+ args: ["double", "double"],
+ },
+ add_int8_t: {
+ returns: "int8_t",
+ args: ["int8_t", "int8_t"],
+ },
+ add_int16_t: {
+ returns: "int16_t",
+ args: ["int16_t", "int16_t"],
+ },
+ add_int32_t: {
+ returns: "int32_t",
+ args: ["int32_t", "int32_t"],
+ },
+ // add_int64_t: {
+ // returns: "int64_t",
+ // args: ["int64_t", "int64_t"],
+ // },
+ add_uint8_t: {
+ returns: "uint8_t",
+ args: ["uint8_t", "uint8_t"],
+ },
+ add_uint16_t: {
+ returns: "uint16_t",
+ args: ["uint16_t", "uint16_t"],
+ },
+ add_uint32_t: {
+ returns: "uint32_t",
+ args: ["uint32_t", "uint32_t"],
+ },
+
+ does_pointer_equal_42_as_int32_t: {
+ returns: "bool",
+ args: ["ptr"],
+ },
+
+ ptr_should_point_to_42_as_int32_t: {
+ returns: "ptr",
+ args: [],
+ },
+ identity_ptr: {
+ returns: "ptr",
+ args: ["ptr"],
+ },
+ // add_uint64_t: {
+ // returns: "uint64_t",
+ // args: ["uint64_t", "uint64_t"],
+ // },
+
+ cb_identity_true: {
+ returns: "bool",
+ args: ["ptr"],
+ },
+ cb_identity_false: {
+ returns: "bool",
+ args: ["ptr"],
+ },
+ cb_identity_42_char: {
+ returns: "char",
+ args: ["ptr"],
+ },
+ // cb_identity_42_float: {
+ // returns: "float",
+ // args: ["ptr"],
+ // },
+ // cb_identity_42_double: {
+ // returns: "double",
+ // args: ["ptr"],
+ // },
+ cb_identity_42_uint8_t: {
+ returns: "uint8_t",
+ args: ["ptr"],
+ },
+ cb_identity_neg_42_int8_t: {
+ returns: "int8_t",
+ args: ["ptr"],
+ },
+ cb_identity_42_uint16_t: {
+ returns: "uint16_t",
+ args: ["ptr"],
+ },
+ cb_identity_42_uint32_t: {
+ returns: "uint32_t",
+ args: ["ptr"],
+ },
+ // cb_identity_42_uint64_t: {
+ // returns: "uint64_t",
+ // args: ["ptr"],
+ // },
+ cb_identity_neg_42_int16_t: {
+ returns: "int16_t",
+ args: ["ptr"],
+ },
+ cb_identity_neg_42_int32_t: {
+ returns: "int32_t",
+ args: ["ptr"],
+ },
+ // cb_identity_neg_42_int64_t: {
+ // returns: "int64_t",
+ // args: ["ptr"],
+ // },
+
+ return_a_function_ptr_to_function_that_returns_true: {
+ returns: "ptr",
+ args: [],
+ },
+};
+
+var opened;
+try {
+ opened = dlopen("/tmp/bun-ffi-test.dylib", types);
+} catch (e) {
+ throw new Error(
+ "Please run `make compile-ffi-test` to compile the ffi test library"
+ );
+}
+
+const {
+ symbols: {
+ returns_true,
+ returns_false,
+ return_a_function_ptr_to_function_that_returns_true,
+ returns_42_char,
+ returns_42_float,
+ returns_42_double,
+ returns_42_uint8_t,
+ returns_neg_42_int8_t,
+ returns_42_uint16_t,
+ returns_42_uint32_t,
+ returns_42_uint64_t,
+ returns_neg_42_int16_t,
+ returns_neg_42_int32_t,
+ returns_neg_42_int64_t,
+ identity_char,
+ identity_float,
+ identity_bool,
+ identity_double,
+ identity_int8_t,
+ identity_int16_t,
+ identity_int32_t,
+ identity_int64_t,
+ identity_uint8_t,
+ identity_uint16_t,
+ identity_uint32_t,
+ identity_uint64_t,
+ add_char,
+ add_float,
+ add_double,
+ add_int8_t,
+ add_int16_t,
+ add_int32_t,
+ add_int64_t,
+ add_uint8_t,
+ add_uint16_t,
+ identity_ptr,
+ add_uint32_t,
+ add_uint64_t,
+ does_pointer_equal_42_as_int32_t,
+ ptr_should_point_to_42_as_int32_t,
+ cb_identity_true,
+ cb_identity_false,
+ cb_identity_42_char,
+ cb_identity_42_float,
+ cb_identity_42_double,
+ cb_identity_42_uint8_t,
+ cb_identity_neg_42_int8_t,
+ cb_identity_42_uint16_t,
+ cb_identity_42_uint32_t,
+ cb_identity_42_uint64_t,
+ cb_identity_neg_42_int16_t,
+ cb_identity_neg_42_int32_t,
+ cb_identity_neg_42_int64_t,
+ },
+ close,
+} = opened;
+
+group("add_int16_t", () => {
+ bench("add_int16_t (raw)", () => raw_add_int16_t(1, 1));
+ bench("add_int16_t", () => add_int16_t(1, 1));
+});
+
+group("add_char", () => {
+ bench("add_char (raw)", () => raw_add_char(1, 1));
+ bench("add_char", () => add_char(1, 1));
+});
+group("add_int16_t", () => {
+ bench("add_int16_t (raw)", () => raw_add_int16_t(1, 1));
+ bench("add_int16_t", () => add_int16_t(1, 1));
+});
+group("add_int32_t", () => {
+ bench("add_int32_t (raw)", () => raw_add_int32_t(1, 1));
+ bench("add_int32_t", () => add_int32_t(1, 1));
+});
+group("add_int8_t", () => {
+ bench("add_int8_t (raw)", () => raw_add_int8_t(1, 1));
+ bench("add_int8_t", () => add_int8_t(1, 1));
+});
+group("add_uint16_t", () => {
+ bench("add_uint16_t (raw)", () => raw_add_uint16_t(1, 1));
+ bench("add_uint16_t", () => add_uint16_t(1, 1));
+});
+group("add_uint32_t", () => {
+ bench("add_uint32_t (raw)", () => raw_add_uint32_t(1, 1));
+ bench("add_uint32_t", () => add_uint32_t(1, 1));
+});
+group("add_uint8_t", () => {
+ bench("add_uint8_t (raw)", () => raw_add_uint8_t(1, 1));
+ bench("add_uint8_t", () => add_uint8_t(1, 1));
+});
+group("identity_bool", () => {
+ bench("identity_bool (raw)", () => raw_identity_bool(false));
+ bench("identity_bool", () => identity_bool(true));
+});
+group("identity_char", () => {
+ bench("identity_char (raw)", () => raw_identity_char(10));
+ bench("identity_char", () => identity_char(10));
+});
+group("identity_int16_t", () => {
+ bench("identity_int16_t (raw)", () => raw_identity_int16_t(10));
+ bench("identity_int16_t", () => identity_int16_t(10));
+});
+group("identity_int32_t", () => {
+ bench("identity_int32_t (raw)", () => raw_identity_int32_t(10));
+ bench("identity_int32_t", () => identity_int32_t(10));
+});
+group("identity_int8_t", () => {
+ bench("identity_int8_t (raw)", () => raw_identity_int8_t(10));
+ bench("identity_int8_t", () => identity_int8_t(10));
+});
+group("identity_uint16_t", () => {
+ bench("identity_uint16_t (raw)", () => raw_identity_uint16_t(10));
+ bench("identity_uint16_t", () => identity_uint16_t(10));
+});
+group("identity_uint32_t", () => {
+ bench("identity_uint32_t (raw)", () => raw_identity_uint32_t(10));
+ bench("identity_uint32_t", () => identity_uint32_t(10));
+});
+group("identity_uint8_t", () => {
+ bench("identity_uint8_t (raw)", () => raw_identity_uint8_t(10));
+ bench("identity_uint8_t", () => identity_uint8_t(10));
+});
+group("returns_42_char", () => {
+ bench("returns_42_char (raw)", () => raw_returns_42_char());
+ bench("returns_42_char", () => returns_42_char());
+});
+group("returns_42_uint16_t", () => {
+ bench("returns_42_uint16_t (raw)", () => raw_returns_42_uint16_t());
+ bench("returns_42_uint16_t", () => returns_42_uint16_t());
+});
+group("returns_42_uint32_t", () => {
+ bench("returns_42_uint32_t (raw)", () => raw_returns_42_uint32_t());
+ bench("returns_42_uint32_t", () => returns_42_uint32_t());
+});
+group("returns_42_uint8_t", () => {
+ bench("returns_42_uint8_t (raw)", () => raw_returns_42_uint8_t());
+ bench("returns_42_uint8_t", () => returns_42_uint8_t());
+});
+group("returns_false", () => {
+ bench("returns_false (raw)", () => raw_returns_false());
+ bench("returns_false", () => returns_false());
+});
+group("returns_neg_42_int16_t", () => {
+ bench("returns_neg_42_int16_t (raw)", () => raw_returns_neg_42_int16_t());
+ bench("returns_neg_42_int16_t", () => returns_neg_42_int16_t());
+});
+group("returns_neg_42_int32_t", () => {
+ bench("returns_neg_42_int32_t (raw)", () => raw_returns_neg_42_int32_t());
+ bench("returns_neg_42_int32_t", () => returns_neg_42_int32_t());
+});
+group("returns_neg_42_int8_t", () => {
+ bench("returns_neg_42_int8_t (raw)", () => raw_returns_neg_42_int8_t());
+ bench("returns_neg_42_int8_t", () => returns_neg_42_int8_t());
+});
+group("returns_true", () => {
+ bench("returns_true (raw)", () => raw_returns_true());
+ bench("returns_true", () => returns_true());
+});
+
+group("return_a_function_ptr_to_function_that_returns_true", () => {
+ bench("return_a_function_ptr_to_function_that_returns_true (raw)", () =>
+ raw_return_a_function_ptr_to_function_that_returns_true()
+ );
+ bench("return_a_function_ptr_to_function_that_returns_true", () =>
+ return_a_function_ptr_to_function_that_returns_true()
+ );
+});
+group("returns_42_float", () => {
+ bench("returns_42_float (raw)", () => raw_returns_42_float());
+ bench("returns_42_float", () => returns_42_float());
+});
+group("returns_42_double", () => {
+ bench("returns_42_double (raw)", () => raw_returns_42_double(42));
+ bench("returns_42_double", () => returns_42_double());
+});
+group("identity_float", () => {
+ bench("identity_float (raw)", () => raw_identity_float(42.42));
+ bench("identity_float", () => identity_float());
+});
+group("identity_double", () => {
+ bench("identity_double (raw)", () => raw_identity_double(42.42));
+ bench("identity_double", () => identity_double());
+});
+
+var raw_return_a_function_ptr_to_function_that_returns_true =
+ return_a_function_ptr_to_function_that_returns_true.native ??
+ return_a_function_ptr_to_function_that_returns_true;
+var raw_returns_42_float = returns_42_float.native ?? returns_42_float;
+var raw_returns_42_double = returns_42_double.native ?? returns_42_double;
+var raw_identity_float = identity_float.native ?? identity_float;
+var raw_identity_double = identity_double.native ?? identity_double;
+var raw_returns_true = returns_true.native ?? returns_true;
+var raw_returns_false = returns_false.native ?? returns_false;
+var raw_returns_42_char = returns_42_char.native ?? returns_42_char;
+var raw_returns_42_uint8_t = returns_42_uint8_t.native ?? returns_42_uint8_t;
+var raw_returns_neg_42_int8_t =
+ returns_neg_42_int8_t.native ?? returns_neg_42_int8_t;
+var raw_returns_42_uint16_t = returns_42_uint16_t.native ?? returns_42_uint16_t;
+var raw_returns_42_uint32_t = returns_42_uint32_t.native ?? returns_42_uint32_t;
+var raw_returns_neg_42_int16_t =
+ returns_neg_42_int16_t.native ?? returns_neg_42_int16_t;
+var raw_returns_neg_42_int32_t =
+ returns_neg_42_int32_t.native ?? returns_neg_42_int32_t;
+var raw_identity_char = identity_char.native ?? identity_char;
+var raw_identity_bool = identity_bool.native ?? identity_bool;
+var raw_identity_bool = identity_bool.native ?? identity_bool;
+var raw_identity_int8_t = identity_int8_t.native ?? identity_int8_t;
+var raw_identity_int16_t = identity_int16_t.native ?? identity_int16_t;
+var raw_identity_int32_t = identity_int32_t.native ?? identity_int32_t;
+var raw_identity_uint8_t = identity_uint8_t.native ?? identity_uint8_t;
+var raw_identity_uint16_t = identity_uint16_t.native ?? identity_uint16_t;
+var raw_identity_uint32_t = identity_uint32_t.native ?? identity_uint32_t;
+var raw_add_char = add_char.native ?? add_char;
+var raw_add_int8_t = add_int8_t.native ?? add_int8_t;
+var raw_add_int16_t = add_int16_t.native ?? add_int16_t;
+var raw_add_int32_t = add_int32_t.native ?? add_int32_t;
+var raw_add_uint8_t = add_uint8_t.native ?? add_uint8_t;
+var raw_add_uint16_t = add_uint16_t.native ?? add_uint16_t;
+var raw_add_uint32_t = add_uint32_t.native ?? add_uint32_t;
+
+run({ collect: false, percentiles: true });