Files
wazero/bench/bench_test.go
Takeshi Yoneda 26ee5eb735 Rename Go source dirs for Wasms to testdata. (#106)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
2021-12-31 17:33:03 +09:00

138 lines
3.5 KiB
Go

package bench
import (
"encoding/binary"
"fmt"
"math/rand"
"os"
"reflect"
"testing"
"github.com/tetratelabs/wazero/wasi"
"github.com/tetratelabs/wazero/wasm"
"github.com/tetratelabs/wazero/wasm/wazeroir"
)
func BenchmarkEngines(b *testing.B) {
b.Run("wazeroir", func(b *testing.B) {
store := newStore(wazeroir.NewEngine())
setUpStore(store)
runAllBenches(b, store)
})
}
func setUpStore(store *wasm.Store) {
buf, err := os.ReadFile("testdata/case.wasm")
if err != nil {
panic(err)
}
mod, err := wasm.DecodeModule((buf))
if err != nil {
panic(err)
}
err = store.Instantiate(mod, "test")
if err != nil {
panic(err)
}
// We assume that TinyGo binary expose "_start" symbol
// to initialize the memory state.
// Meaning that TinyGo binary is "WASI command":
// https://github.com/WebAssembly/WASI/blob/main/design/application-abi.md
_, _, err = store.CallFunction("test", "_start")
if err != nil {
panic(err)
}
}
func runAllBenches(b *testing.B, store *wasm.Store) {
runBase64Benches(b, store)
runFibBenches(b, store)
runStringsManipulationBenches(b, store)
runReverseArrayBenches(b, store)
runRandomMatMul(b, store)
}
func runBase64Benches(b *testing.B, store *wasm.Store) {
for _, numPerExec := range []int{5, 100, 10000} {
b.ResetTimer()
b.Run(fmt.Sprintf("base64_%d_per_exec", numPerExec), func(b *testing.B) {
_, _, err := store.CallFunction("test", "base64", uint64(numPerExec))
if err != nil {
panic(err)
}
})
}
}
func runFibBenches(b *testing.B, store *wasm.Store) {
for _, num := range []int{5, 10, 20} {
b.ResetTimer()
b.Run(fmt.Sprintf("fib_for_%d", num), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _, err := store.CallFunction("test", "fibonacci", uint64(num))
if err != nil {
panic(err)
}
}
})
}
}
func runStringsManipulationBenches(b *testing.B, store *wasm.Store) {
for _, initialSize := range []int{50, 100, 1000} {
b.ResetTimer()
b.Run(fmt.Sprintf("string_manipulation_size_%d", initialSize), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _, err := store.CallFunction("test", "string_manipulation", uint64(initialSize))
if err != nil {
panic(err)
}
}
})
}
}
func runReverseArrayBenches(b *testing.B, store *wasm.Store) {
for _, arraySize := range []int{500, 1000, 10000} {
b.ResetTimer()
b.Run(fmt.Sprintf("reverse_array_size_%d", arraySize), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _, err := store.CallFunction("test", "reverse_array", uint64(arraySize))
if err != nil {
panic(err)
}
}
})
}
}
func runRandomMatMul(b *testing.B, store *wasm.Store) {
for _, matrixSize := range []int{5, 10, 100} {
b.ResetTimer()
b.Run(fmt.Sprintf("random_mat_mul_size_%d", matrixSize), func(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _, err := store.CallFunction("test", "random_mat_mul", uint64(matrixSize))
if err != nil {
panic(err)
}
}
})
}
}
func newStore(engine wasm.Engine) *wasm.Store {
store := wasm.NewStore(engine)
getRandomString := func(ctx *wasm.HostFunctionCallContext, retBufPtr uint32, retBufSize uint32) {
ret, _, _ := store.CallFunction("test", "allocate_buffer", 10)
bufAddr := ret[0]
binary.LittleEndian.PutUint32(ctx.Memory.Buffer[retBufPtr:], uint32(bufAddr))
binary.LittleEndian.PutUint32(ctx.Memory.Buffer[retBufSize:], 10)
_, _ = rand.Read(ctx.Memory.Buffer[bufAddr : bufAddr+10])
}
_ = store.AddHostFunction("env", "get_random_string", reflect.ValueOf(getRandomString))
_ = wasi.NewEnvironment().Register(store)
return store
}