Skip to content

Commit 78db050

Browse files
authored
Merge pull request #30 from danleh/sqlite-scoring
Move sqlite Wasm benchmark to first, worst, average scoring
2 parents fa77231 + ebddd39 commit 78db050

File tree

7 files changed

+148
-154
lines changed

7 files changed

+148
-154
lines changed

JetStreamDriver.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,17 +2001,17 @@ const BENCHMARKS = [
20012001
worstCaseCount: 2,
20022002
testGroup: WasmGroup
20032003
}),
2004-
new WasmLegacyBenchmark({
2004+
new WasmEMCCBenchmark({
20052005
name: "sqlite3-wasm",
20062006
files: [
2007-
"./sqlite3/polyfills.js",
2008-
"./sqlite3/build/jswasm/speedtest1.js",
20092007
"./sqlite3/benchmark.js",
2008+
"./sqlite3/build/jswasm/speedtest1.js",
20102009
],
20112010
preload: {
20122011
wasmBinary: "./sqlite3/build/jswasm/speedtest1.wasm"
20132012
},
2014-
benchmarkClass: WasmLegacyBenchmark,
2013+
iterations: 15,
2014+
worstCaseCount: 2,
20152015
testGroup: WasmGroup
20162016
}),
20172017
new WasmLegacyBenchmark({

sqlite3/benchmark.js

Lines changed: 79 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,72 +2,97 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
const inJetStreamRunner = typeof globalThis.benchmarkTime !== "undefined";
6-
if (!inJetStreamRunner) {
7-
load("polyfills.js");
5+
// First, some polyfills for missing browser APIs in JavaScript shells.
6+
// Since the generated JavaScript code of SQLite immediately uses some of them,
7+
// we need to load and run this code before the generated `speedtest1.js` in the
8+
// JetStream driver.
89

9-
// Exports `sqlite3InitModule()` and contains the main code.
10-
load("build/jswasm/speedtest1.js");
10+
// Empty `URLSearchParams` has just the same interface as a `Map`.
11+
globalThis.URLSearchParams = Map;
1112

12-
// Load Wasm binary from disk.
13-
globalThis.Module = {
14-
wasmBinary: read("build/jswasm/speedtest1.wasm", "binary"),
15-
};
13+
// `TextEncoder` and `TextDecoder`. These are called only a few times with short
14+
// ASCII strings, so this is sufficient and not performance-critical.
15+
class TextEncoder {
16+
encode(string) {
17+
return Uint8Array.from(string, (char) => {
18+
let byte = char.codePointAt(0);
19+
if (byte > 0x7f)
20+
throw new Error("TextEncoder polyfill only supports ASCII");
21+
return byte;
22+
});
23+
}
24+
}
25+
class TextDecoder {
26+
decode(array) {
27+
for (let byte of array) {
28+
if (byte > 0x7f)
29+
throw new Error("TextDecoder polyfill only supports ASCII");
30+
}
31+
return String.fromCharCode.apply(null, array);
32+
}
1633
}
1734

35+
// Now, some configuration options for when we initialize SQLite.
36+
37+
// Use JetStream functions instead of `console.log` and friends.
38+
globalThis.sqlite3ApiConfig = {
39+
log: print,
40+
debug: print,
41+
warn: print,
42+
error: print,
43+
};
44+
1845
// Make sure we never initialize OPFS by removing one of it's APIs (see
1946
// `installOpfsVfs` in the generated JavaScript code of sqlite).
2047
// We never want to use it anyway (see VFS config below) and this way we don't
2148
// waste cycles on the browser runner to initialize it.
2249
delete globalThis.FileSystemHandle;
2350

24-
// Simplified from inline JavaScript in `speedtest1.html`.
25-
function runTests(sqlite3Module) {
26-
// Configure the VFS to use.
27-
// Don't use OPFS, WASMFS (which is on top of OPFS), or kvvfs, since they all
28-
// use persistent browser storage (localStorage or OPFS), which is not
29-
// available in JavaScript shells.
30-
// Also don't use memfs, since that crashes with a NULL function pointer.
31-
// Instead, make the default VFS explicit.
32-
const capi = sqlite3Module.capi
33-
console.log("Available SQLite VFS:", capi.sqlite3_js_vfs_list());
34-
const vfs = "unix";
35-
console.log("Using VFS:", vfs);
36-
const pVfs = capi.sqlite3_vfs_find(vfs);
37-
if (!pVfs) {
38-
console.error("Error: Unknown VFS:", vfs);
39-
return;
40-
}
51+
class Benchmark {
52+
sqlite3Module;
4153

42-
// These arguments should match the upstream browser runner `speedtest1.html`.
43-
let argv = [
44-
"speedtest1",
45-
"--singlethread",
46-
//"--nomutex",
47-
//"--nosync",
48-
//"--memdb", // note that memdb trumps the filename arg
49-
"--nomemstat",
50-
"--big-transactions" /*important for tests 410 and 510!*/,
51-
"--size", "20", // To speedup, default is 100 (and takes about 4s).
52-
"--vfs", vfs, // See VFS comment above.
53-
];
54+
async runIteration() {
55+
if (!this.sqlite3Module) {
56+
// Defined in the generated SQLite JavaScript code.
57+
// Different in details but seemingly related/inspired by Emscripten code.
58+
this.sqlite3Module = await sqlite3InitModule(Module);
59+
}
5460

55-
console.log("Calling main with argv:", argv);
56-
const wasm = sqlite3Module.wasm;
57-
wasm.scopedAllocPush(); // Required for `scopedAllocMainArgv()`.
58-
wasm.xCall("wasm_main", argv.length, wasm.scopedAllocMainArgv(argv));
59-
wasm.scopedAllocPop();
60-
}
61+
// The following is simplified from inline JavaScript in `speedtest1.html`.
62+
63+
// Configure the VFS to use.
64+
// Don't use OPFS, WASMFS (which is on top of OPFS), or kvvfs, since they
65+
// all use persistent browser storage (localStorage or OPFS), which is not
66+
// available in JavaScript shells.
67+
// Also don't use memfs, since that crashes with a NULL function pointer.
68+
// Instead, make the default VFS explicit.
69+
const capi = this.sqlite3Module.capi
70+
print("Available SQLite VFS:", capi.sqlite3_js_vfs_list());
71+
const vfs = "unix";
72+
print("Using VFS:", vfs);
73+
const pVfs = capi.sqlite3_vfs_find(vfs);
74+
if (!pVfs) {
75+
throw new Error("Unknown VFS:", vfs);
76+
}
6177

62-
async function doRun() {
63-
let start = benchmarkTime();
64-
const sqliteModule = await sqlite3InitModule(Module);
65-
reportCompileTime(benchmarkTime() - start);
78+
// These arguments should match the upstream browser runner in
79+
// `speedtest1.html`, except for the --size parameter.
80+
let argv = [
81+
"speedtest1",
82+
"--singlethread",
83+
//"--nomutex",
84+
//"--nosync",
85+
//"--memdb", // note that memdb trumps the filename arg
86+
"--nomemstat",
87+
"--big-transactions" /*important for tests 410 and 510!*/,
88+
"--size", "10", // To speedup, default is 100 (and takes about 4s).
89+
"--vfs", vfs, // See VFS comment above.
90+
];
6691

67-
start = benchmarkTime();
68-
runTests(sqliteModule);
69-
reportRunTime(benchmarkTime() - start);
70-
}
71-
if (!inJetStreamRunner) {
72-
sqlite3InitModule(Module).then(runTests);
92+
print("Calling main with argv:", argv);
93+
const wasm = this.sqlite3Module.wasm;
94+
wasm.scopedAllocPush(); // Required for `scopedAllocMainArgv()`.
95+
wasm.xCall("wasm_main", argv.length, wasm.scopedAllocMainArgv(argv));
96+
wasm.scopedAllocPop();
97+
}
7398
}

sqlite3/build.log

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
Built on 2024-12-05 14:24:19+01:00
1+
Built on 2025-01-21T15:10:24Z
22

33
Toolchain versions
4-
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.71 (4171ae200b77a6c266b0e1ebb507d61d1ade3501)
4+
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.73 (ac676d5e437525d15df5fd46bc2c208ec6d376a3)
55
wasm-strip 1.0.34
66

7-
Getting sources from https://sqlite.org/2024/sqlite-src-3470100.zip
7+
Getting sources from https://sqlite.org/2025/sqlite-src-3480000.zip
88

99
Building...
1010
Copying files from sqlite-src-*/ext/wasm/ into build/

sqlite3/build.sh

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
#!/bin/bash
22

3-
set -e
4-
set -o pipefail
3+
set -eo pipefail
54

65
# Cleanup old files.
7-
rm sqlite-src-*.zip
6+
rm -f sqlite-src-*.zip
87
rm -rf sqlite-src-*/
98
rm -rf build/
109

@@ -17,7 +16,7 @@ emcc --version | head -n1 | tee -a "$BUILD_LOG"
1716
echo -e "wasm-strip $(wasm-strip --version)\n" | tee -a "$BUILD_LOG"
1817

1918
# Check https://sqlite.org/download.html and update the source link, if needed.
20-
SQLITE_SRC_URL="https://sqlite.org/2024/sqlite-src-3470100.zip"
19+
SQLITE_SRC_URL="https://sqlite.org/2025/sqlite-src-3480000.zip"
2120
echo -e "Getting sources from $SQLITE_SRC_URL\n" | tee -a "$BUILD_LOG"
2221
SQLITE_SRC_FILE="$(basename $SQLITE_SRC_URL)"
2322
curl -o "$SQLITE_SRC_FILE" $SQLITE_SRC_URL

0 commit comments

Comments
 (0)