Slow latency on first query? · ncruces/go-sqlite3 · Discussion #32 (original) (raw)
Yes, this is expected behaviour, though maybe it should be documented better.
We embed a Wasm version of SQLite. This needs to be compiled to machine code on the first instantiation:
| func instantiateSQLite() (sqlt *sqlite, err error) { |
|---|
| instance.once.Do(compileSQLite) |
wazero (our WASM runtime) is quite fast at compiling, but the WASM file is also quite big (1.4Mb), hence the slowdown.
There are 3 ways to mitigate this cost:
- compile at a more appropriate time
- cache the compilation result
- slim down SQLite to reduce compilation time
Compile at a more appropriate time
This should do the job:
if err := sqlite3.Initialize(); err != nil { log.Fatal(err) }
You can also do this in a background goroutine.
Cache the compilation result
You can provide your own wazero.RuntimeConfig, by setting sqlite3.RuntimeConfig. This allows you to configure the compilation cache, choose between the compiler/interpreter, limit memory, etc…) The cache can speed up first instantiation by an order of magnitude.
Slim down SQLite to reduce compilation time
If you can do away with some of the optional features, one way to improve the situation is to generate your own, slimmed down, sqlite3.wasm. You can also trade speed for size (-O3 vs -Os).
All you need is wasi-sdk, and binaryen. You can edit sqlite_opt.h to remove some of the extensions (FTS, R*Tree, GeoPoly are good candidates if you don't need them). And tweak compile options in the build.sh script. To load your own build of SQLite, you can change either the Binary or Path variables, instead of importing embed.