mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
Add SQLite speedtest1.
This commit is contained in:
@@ -20,7 +20,7 @@ embeds a build of SQLite into your application.
|
||||
|
||||
This module replaces the SQLite [OS Interface](https://www.sqlite.org/vfs.html) (aka VFS)
|
||||
with a pure Go implementation.
|
||||
This has numerous benefits, but also comes with some caveats.
|
||||
This has numerous benefits, but also comes with some drawbacks.
|
||||
|
||||
#### Write-Ahead Logging
|
||||
|
||||
@@ -55,6 +55,9 @@ The pure Go VFS is stress tested by running an unmodified build of SQLite's
|
||||
[mptest](https://github.com/sqlite/sqlite/blob/master/mptest/mptest.c)
|
||||
on Linux, macOS and Windows.
|
||||
|
||||
Performance is tested by running
|
||||
[speedtest1](https://github.com/sqlite/sqlite/blob/master/test/speedtest1.c).
|
||||
|
||||
### Roadmap
|
||||
|
||||
- [ ] advanced SQLite features
|
||||
|
||||
@@ -99,11 +99,12 @@ func Test_config01(t *testing.T) {
|
||||
ctx, vfs := vfsContext(newContext(t))
|
||||
name := filepath.Join(t.TempDir(), "test.db")
|
||||
cfg := config(ctx).WithArgs("mptest", name, "config01.test")
|
||||
_, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
mod, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
vfs.Close()
|
||||
mod.Close(ctx)
|
||||
}
|
||||
|
||||
func Test_config02(t *testing.T) {
|
||||
@@ -117,11 +118,12 @@ func Test_config02(t *testing.T) {
|
||||
ctx, vfs := vfsContext(newContext(t))
|
||||
name := filepath.Join(t.TempDir(), "test.db")
|
||||
cfg := config(ctx).WithArgs("mptest", name, "config02.test")
|
||||
_, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
mod, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
vfs.Close()
|
||||
mod.Close(ctx)
|
||||
}
|
||||
|
||||
func Test_crash01(t *testing.T) {
|
||||
@@ -132,11 +134,12 @@ func Test_crash01(t *testing.T) {
|
||||
ctx, vfs := vfsContext(newContext(t))
|
||||
name := filepath.Join(t.TempDir(), "test.db")
|
||||
cfg := config(ctx).WithArgs("mptest", name, "crash01.test")
|
||||
_, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
mod, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
vfs.Close()
|
||||
mod.Close(ctx)
|
||||
}
|
||||
|
||||
func Test_multiwrite01(t *testing.T) {
|
||||
@@ -147,11 +150,12 @@ func Test_multiwrite01(t *testing.T) {
|
||||
ctx, vfs := vfsContext(newContext(t))
|
||||
name := filepath.Join(t.TempDir(), "test.db")
|
||||
cfg := config(ctx).WithArgs("mptest", name, "multiwrite01.test")
|
||||
_, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
mod, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
vfs.Close()
|
||||
mod.Close(ctx)
|
||||
}
|
||||
|
||||
func newContext(t *testing.T) context.Context {
|
||||
|
||||
12
tests/mptest/testdata/build.sh
vendored
12
tests/mptest/testdata/build.sh
vendored
@@ -4,12 +4,12 @@ set -eo pipefail
|
||||
cd -P -- "$(dirname -- "$0")"
|
||||
|
||||
if [ ! -f "mptest.c" ]; then
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/master/mptest/mptest.c"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/master/mptest/config01.test"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/master/mptest/config02.test"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/master/mptest/crash01.test"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/master/mptest/crash02.subtest"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/master/mptest/multiwrite01.test"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/version-3.41.1/mptest/mptest.c"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/version-3.41.1/mptest/config01.test"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/version-3.41.1/mptest/config02.test"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/version-3.41.1/mptest/crash01.test"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/version-3.41.1/mptest/crash02.subtest"
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/version-3.41.1/mptest/multiwrite01.test"
|
||||
fi
|
||||
|
||||
zig cc --target=wasm32-wasi -flto -g0 -Os \
|
||||
|
||||
92
tests/speedtest1/speedtest1_test.go
Normal file
92
tests/speedtest1/speedtest1_test.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package speedtest1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
_ "embed"
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/tetratelabs/wazero"
|
||||
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
|
||||
|
||||
_ "github.com/ncruces/go-sqlite3"
|
||||
)
|
||||
|
||||
//go:embed testdata/speedtest1.wasm
|
||||
var binary []byte
|
||||
|
||||
//go:linkname vfsNewEnvModuleBuilder github.com/ncruces/go-sqlite3.vfsNewEnvModuleBuilder
|
||||
func vfsNewEnvModuleBuilder(r wazero.Runtime) wazero.HostModuleBuilder
|
||||
|
||||
//go:linkname vfsContext github.com/ncruces/go-sqlite3.vfsContext
|
||||
func vfsContext(ctx context.Context) (context.Context, io.Closer)
|
||||
|
||||
var (
|
||||
rt wazero.Runtime
|
||||
module wazero.CompiledModule
|
||||
output bytes.Buffer
|
||||
options []string
|
||||
)
|
||||
|
||||
func init() {
|
||||
ctx := context.TODO()
|
||||
|
||||
rt = wazero.NewRuntime(ctx)
|
||||
wasi_snapshot_preview1.MustInstantiate(ctx, rt)
|
||||
env := vfsNewEnvModuleBuilder(rt)
|
||||
_, err := env.Instantiate(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
module, err = rt.CompileModule(ctx, binary)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
i := 1
|
||||
options = append(options, "speedtest1")
|
||||
for _, arg := range os.Args[1:] {
|
||||
if strings.HasPrefix(arg, "-test.") {
|
||||
os.Args[i] = arg
|
||||
i++
|
||||
} else {
|
||||
options = append(options, arg)
|
||||
}
|
||||
}
|
||||
os.Args = os.Args[:i]
|
||||
|
||||
code := m.Run()
|
||||
io.Copy(os.Stderr, &output)
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func Benchmark_speedtest1(b *testing.B) {
|
||||
output.Reset()
|
||||
ctx, vfs := vfsContext(context.Background())
|
||||
name := filepath.Join(b.TempDir(), "test.db")
|
||||
args := append(options, "--size", strconv.Itoa(b.N), name)
|
||||
cfg := wazero.NewModuleConfig().
|
||||
WithArgs(args...).WithName("speedtest1").
|
||||
WithStdout(&output).WithStderr(&output).
|
||||
WithSysWalltime().WithSysNanotime().WithSysNanosleep().
|
||||
WithOsyield(runtime.Gosched).
|
||||
WithRandSource(rand.Reader)
|
||||
mod, err := rt.InstantiateModule(ctx, module, cfg)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
vfs.Close()
|
||||
mod.Close(ctx)
|
||||
}
|
||||
1
tests/speedtest1/testdata/.gitattributes
vendored
Normal file
1
tests/speedtest1/testdata/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
speedtest1.wasm filter=lfs diff=lfs merge=lfs -text
|
||||
1
tests/speedtest1/testdata/.gitignore
vendored
Normal file
1
tests/speedtest1/testdata/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
speedtest1.c
|
||||
21
tests/speedtest1/testdata/build.sh
vendored
Executable file
21
tests/speedtest1/testdata/build.sh
vendored
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
cd -P -- "$(dirname -- "$0")"
|
||||
|
||||
if [ ! -f "mptest.c" ]; then
|
||||
curl -sOL "https://github.com/sqlite/sqlite/raw/version-3.41.1/test/speedtest1.c"
|
||||
fi
|
||||
|
||||
zig cc --target=wasm32-wasi -flto -g0 -Os \
|
||||
-o speedtest1.wasm main.c \
|
||||
-I../../../sqlite3 \
|
||||
-mmutable-globals \
|
||||
-mbulk-memory -mreference-types \
|
||||
-mnontrapping-fptoint -msign-ext \
|
||||
-D_HAVE_SQLITE_CONFIG_H
|
||||
|
||||
if which wasm-opt; then
|
||||
wasm-opt -g -O -o speedtest1.tmp speedtest1.wasm
|
||||
mv speedtest1.tmp speedtest1.wasm
|
||||
fi
|
||||
20
tests/speedtest1/testdata/main.c
vendored
Normal file
20
tests/speedtest1/testdata/main.c
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "sqlite3.c"
|
||||
//
|
||||
#include "os.c"
|
||||
#include "qsort.c"
|
||||
#include "time.c"
|
||||
|
||||
sqlite3_destructor_type malloc_destructor = &free;
|
||||
size_t sqlite3_interrupt_offset = offsetof(sqlite3, u1.isInterrupted);
|
||||
|
||||
int sqlite3_os_init() {
|
||||
return sqlite3_vfs_register(os_vfs(), /*default=*/true);
|
||||
}
|
||||
|
||||
__attribute__((constructor)) void premain() { sqlite3_initialize(); }
|
||||
|
||||
#define randomFunc(args...) randomFunc2(args)
|
||||
#include "speedtest1.c"
|
||||
3
tests/speedtest1/testdata/speedtest1.wasm
vendored
Normal file
3
tests/speedtest1/testdata/speedtest1.wasm
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:996c2445ad12c91dce1a59ab5929cfaa3a09a4ac82859fecc7de5e5f9c955f80
|
||||
size 1001607
|
||||
Reference in New Issue
Block a user