Skip to content

Instantly share code, notes, and snippets.

@billywhizz
Created September 5, 2024 11:54
Show Gist options
  • Save billywhizz/271e25da48f8dec6ceaa9bf2ab7fcad5 to your computer and use it in GitHub Desktop.
Save billywhizz/271e25da48f8dec6ceaa9bf2ab7fcad5 to your computer and use it in GitHub Desktop.
Porffor static link benchmark code
const SQLITE3_OK = 0;
const SQLITE3_ROW = 100;
const SQLITE3_OPEN_READWRITE = 0x00000002;
const SQLITE3_OPEN_CREATE = 0x00000004;
const SQLITE3_OPEN_MEMORY = 0x00000080;
const SQLITE3_OPEN_PRIVATECACHE = 0x00040000;
const SQLITE3_OPEN_NOMUTEX = 0x00008000;
function assert (condition, message) {
if (!condition) {
throw new Error(message)
}
return condition
}
const unwrap = (code) => {
if (code === SQLITE3_OK) return;
throw new Error(`SQLite error: ${code}`);
};
const passTA = (ta) => {
return Porffor.wasm.i32.load(ta, 0, 4);
};
const {
strnlen,
write,
close,
pread,
lseek,
fstat,
fcntl,
ftruncate,
read,
open,
sleep
} = Porffor.dlopen("\0", {
strnlen: {
parameters: ['buffer', 'i32'],
result: 'i32',
},
write: {
parameters: ['i32', 'buffer', 'i32'],
result: 'i32'
},
close: {
parameters: ['i32'],
result: 'i32'
},
pread: {
parameters: ['i32', 'buffer', 'u32', 'u32'],
result: 'i32'
},
lseek: {
parameters: ['i32', 'u32', 'i32'],
result: 'u32'
},
fstat: {
parameters: ['i32', 'buffer'],
result: 'i32'
},
fcntl: {
parameters: ['i32', 'i32', 'i32'],
result: 'i32'
},
ftruncate: {
parameters: ['i32', 'u32'],
result: 'i32'
},
read: {
parameters: ['i32', 'buffer', 'i32'],
result: 'i32'
},
open: {
parameters: ['buffer', 'i32', 'i32'],
result: 'i32'
},
sleep: {
parameters: ['u32'],
result: 'i32'
}
}, [
'unistd.h', 'sys/stat.h', 'fcntl.h', 'dirent.h', 'dlfcn.h', 'stdio.h', 'string.h'
]);
const {
sqlite3_open_v2,
sqlite3_exec,
sqlite3_prepare_v2,
sqlite3_reset,
sqlite3_finalize,
sqlite3_step,
sqlite3_column_int,
sqlite3_initialize,
} = Porffor.dlopen("./libsqlite3.so", {
sqlite3_initialize: {
parameters: [],
result: 'i32'
},
sqlite3_open_v2: {
parameters: [
"buffer", // const char *filename
"buffer", // sqlite3 **ppDb
"i32", // int flags
"pointer", // const char *zVfs
],
result: "i32",
},
sqlite3_exec: {
parameters: [
"pointer", // sqlite3 *db
"buffer", // const char *sql
"pointer", // sqlite3_callback callback
"pointer", // void *arg
"pointer", // char **errmsg
],
result: "i32",
},
sqlite3_prepare_v2: {
parameters: [
"pointer", // sqlite3 *db
"buffer", // const char *zSql
"i32", // int nByte
"buffer", // sqlite3_stmt **ppStmt
"pointer", // const char **pzTail
],
result: "i32",
},
sqlite3_reset: {
parameters: [
"pointer", // sqlite3_stmt *pStmt
],
result: "i32",
},
sqlite3_finalize: {
parameters: [
"pointer", // sqlite3_stmt *pStmt
],
result: "i32",
},
sqlite3_step: {
parameters: [
"pointer", // sqlite3_stmt *pStmt
],
result: "i32",
},
sqlite3_column_int: {
parameters: [
"pointer", // sqlite3_stmt *pStmt
"i32", // int iCol
],
result: "i32",
},
}, ["sqlite3.h"]);
if (sqlite3_initialize() != 0) throw new Error('Could not Initialize')
const pHandle = new Uint32Array(2);
unwrap(sqlite3_open_v2(
":memory:",
passTA(pHandle),
SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_NOMUTEX,
null
));
const db = pHandle[0] + pHandle[1]*4294967296;
function exec(sql) {
unwrap(sqlite3_exec(db, sql, null, null, null));
}
exec("PRAGMA auto_vacuum = none");
exec("PRAGMA temp_store = memory");
exec("PRAGMA locking_mode = exclusive");
exec("PRAGMA user_version = 100");
function prepareStatement(sql) {
const out = new Uint32Array(2);
unwrap(sqlite3_prepare_v2(
db,
sql,
sql.length,
passTA(out),
null
));
return out[0] + out[1]*4294967296;
}
const get_version_prepared = prepareStatement('pragma user_version')
const get_version = () => {
if(sqlite3_step(get_version_prepared) == SQLITE3_ROW) {
const v = sqlite3_column_int(get_version_prepared, 0);
assert(sqlite3_reset(get_version_prepared) == SQLITE3_OK);
return v;
}
assert(sqlite3_finalize(get_version_prepared) == SQLITE3_OK);
return 0;
};
const bench = () => {
const runs = 10_000_000;
const start = performance.now();
for (let i = 0; i < runs; i++) assert((get_version() == 100));
const elapsed = Math.floor(performance.now() - start);
const rate = Math.floor(runs / (elapsed / 1000));
console.log(['time', elapsed, 'ops/sec', rate]);
};
assert(get_version() == 100);
for (let i = 0; i < 10; i++) bench();
assert(sqlite3_finalize(get_version_prepared) == SQLITE3_OK);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment