Skip to content

wazero v1.0.0-pre.6

Pre-release
Pre-release
Compare
Choose a tag to compare
@codefromthecrypt codefromthecrypt released this 31 Dec 13:16
· 1103 commits to main since this release
94491fe

wazero v1.0.0-pre.6 improves performance, CLI and adds a writeable filesystem.

Performance, reliability and usability have been recurring trends in wazero this year, and they will continue into next. We're thankful to have so many end users and enthusiasts active, and wow.. it was an active month!

Performance

This December, @mathetake has been working hard on the compiler backend, while @ckaznocha put in time to optimize various parts of module initialization. We've also put many more benchmarks in place including I/O functions like WASI. Results were dramatic.

For example, our benchmark of go compiled to wasm (GOOS=js GOARCH=wasm) improved almost 25%, while our benchmark for WASI+TinyGo improved compilation time by almost 25% and instantiation time nearly 10%.

While these improvements are great, wazero still won't beat optimizing compilers. The good news is that @mathetake proved it is possible to do JIT-ish compilation and execution in pure Go. Moreover, Tetrate has hired an extremely bright engineer to start working with Takeshi on this problem next month. For those interested in how wazero works today, take a look at this year's GopherCon presentation.

CLI

wazero works with diverse wasm compilers. Many re-use the same libraries to perform tasks such as I/O, like wasi-libc. However, even those who use that routinely drop down to pure wasm functions to optimize or decouple. Moreover, Go's compiler uses its own syscall ABI which is unlike WASI. In order for us to be more efficient, we've significantly enhanced our CLI.

Most notably, we added --hostlogging=filesystem which can show you what's happening during a command.

$ tinygo build -target wasi -o cat.wasm cat.go
$ echo hello world > /tmp/hello.txt
$ wazero run -mount=/tmp:/ --hostlogging=filesystem cat.wasm /hello.txt
==> wasi_snapshot_preview1.fd_prestat_get(fd=3)
<== (prestat={pr_name_len=1},errno=ESUCCESS)
--snip--

We also detect if you are using Go generated wasm automatically now (GOOS=js GOARCH=wasm). We support logging on that, even though the functions underneath act wildly differently.

$ GOARCH=wasm GOOS=js go build -o cat.wasm cat.go
$ wazero run -mount=/tmp:/ --hostlogging=filesystem cat.wasm /hello.txt
==> go.syscall/js.valueCall(fs.open(name=/hello.txt,flags=,perm=----------))
<== (err=<nil>,fd=4)
--snip--

We've also added a -cachedir flag which allows running the same wasm faster the second time. Those building images can use the compile command first, as that allows you to build cache without actually executing the module.

Ex. This command took almost 140ms as it implied compilation. By precompiling, it executes 100ms quicker.

$ time wazero run -mount=/tmp:/ cat.wasm /hello.txt
hello world

real	0m0.139s
user	0m0.178s
sys	0m0.036s

$ wazero compile -cachedir=$HOME/.wazero cat.wasm
$ time wazero run  -cachedir=$HOME/.wazero -mount=/tmp:/ cat.wasm /hello.txt
hello world

real	0m0.038s
user	0m0.018s
sys	0m0.019s

Finally, we added wazero version command, which does what you think it would. Thanks to @codefromthecrypt and @mathetake for the work here.

Writeable filesystem

Getting filesystem I/O working properly in sandboxed wasm across different compilers is an arduous task. We've had a lot of help this release from @vyskocilm @ncruces and @robbertvanginkel getting various system calls working as they should. Recently, @achille-roussel offered to help with polishing up things to allow users to plug-in their own filesystems in a way that goes beyond the limitations of Go's fs.FS. Notably, while fs.FS allows writing existing files, it has no support for routine tasks such as creating, renaming or deleting files.

While we are at least a month, possibly two from a plug-in abstraction, but meanwhile we added a new hook that allows you to opt into write support.

fs, err := writefs.NewDirFS("/work/appA")
if err != nil {
	log.Panicln(err)
}
config = wazero.NewModuleConfig().WithFS(fs)

writefs.NewDirFS currently adds creating, renaming and deleting files, and thanks to @achille-roussel we now have better virtualized file descriptors.

January we will continue to complete syscall support in our internal abstraction. This takes a long time, as we like to do things right, by vetting against multiple compilers such as zig, clang, TinyGo and normal Go. We'll setup as many tests as we can, including running TinyGo and Go's stdlib tests with wazero, and wasi-testsuite. Once all of that is working and documented, we'll expose an pluggable API, even if it means slipping our 1.0 release from end of February to March. Meanwhile, we're thrilled to have @achille-roussel contributing code and guidance.

Getting in touch

The wazero team hangs out in two channels in gophers slack: #wazero and #wazero-dev. Note: You may need an invite to join gophers. If you like what we are doing, please star our repo as folks appreciate it.

We also attend conferences who accept our talks: The next up is that.us covering backend WebAssembly use cases in wazero. Please encourage conferences you like to consider wazero, as it is a unique and useful part of both Go programming and WebAssembly landscape.

Regardless, Happy New Year! Thanks for all the engagement that made 2022 so exciting and productive: we're thrilled to continue that forward.