Created
September 5, 2024 11:54
-
-
Save billywhizz/271e25da48f8dec6ceaa9bf2ab7fcad5 to your computer and use it in GitHub Desktop.
Porffor static link benchmark code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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