Skip to content

Simple Web Assembly application with Go runtime and Swift binary

Notifications You must be signed in to change notification settings

hassan-shahbazi/swiftwasm-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Swift + Web Assembly

This repository contains all code related to a 3-part tutorial published on Medium: Part 1, Part 2, and Part 3

Requirements

  • Ubuntu >= 18.04. (macOS naturally works fine, but I have not tested it yet)
  • Go >= 1.15
  • swift-wasm >= wasm-5.3.1-RELEASE

Installation

Running

  1. Set the correct version of Swiftwasm

    $ swiftenv global wasm-5.3.1-RELEASE
  2. Build Swift project and generate wasm binary:

    $ TOOLCHAIN_PATH=$(cd $(dirname "$(swiftenv which swiftc)") && cd ../share && pwd)
    $ swift build --triple wasm32-unknown-wasi -c release --toolchain $TOOLCHAIN_PATH -Xlinker --export=allocate -Xlinker --export=deallocate -Xlinker --export=hello -Xlinker --export=sum -Xlinker --export=concatenate -Xlinker --export=fetch -Xlinker --allow-undefined
  3. Copy wasm to the project's directory

$ cp swiftwasm/.build/release/swiftwasm.wasm ../binary.wasm
  1. (optionally) Run tests
$ binary=swift go test ./... -v -race -count 1 -run _Swift
  1. Run the Go application
    $ go run ./
    > Hello World!
    > '_start' called, but returned void: true
    > 'save' exported function: 3
    > 'concatenate' exported function with string parameters: World World!
    > 'fetch_code imported function input: 2' 4

Benchmark

With the first stable version of swiftwasm (wasm-5.3.1-RELEASE), a swift generated binary offers a larger binary with a significantly poor performance comparing to Rust. The project contains a Rust sample project for comparison purposes.

Size

The following comparison shows the binary size for a same set of functions in Rust and Swift, 1.7M and 9.8M respectively. The Swift binary is about 5 times larger than the Rust one.

$ ls -lh rust | grep wasm
-rwxrwxr-x 1 hassan hassan 1.7M Oct 30 20:33 binary.wasm

$ ls -lh swiftwasm | grep wasm
-rwxrwxr-x 1 hassan hassan 9.8M Oct 26 17:08 binary.wasm

Performance

Larger binary size is not the only issue with Swift generated binaries. The more important issue is where wasmer is almost 32 times slower in running Swift binaries comparing to Rust binaries with identical functions. With the execution times are same for both Rust and Swift, the main issue with Swift binary seems to be wasmer compilation issue for large binaries.

$ binary=rust go test ./... -race -count 1 -run _Rust
ok  	github.com/hassan-shahbazi/swiftwasi/src	0.214s

$ binary=swift go test ./... -race -count 1 -run _Swift
ok  	github.com/hassan-shahbazi/swiftwasi/src	6.899s

Optimization

Discussed in #2135, using wasm-opt -0s can significantly improve binary size from 9.8M to 4.4M which results in a the performance improvement from 6.899s to 3.547s.

$ ~/binaryen/bin/wasm-opt swiftwasm/binary.wasm -o swiftwasm/binary.wasm -Os

$ ls -lh swiftwasm | grep wasm
-rwxrwxr-x 1 hassan hassan 4.4M Nov 30 16:12 binary.wasm

$ binary=swift go test ./... -race -count 1 run _Swift
ok  	github.com/hassan-shahbazi/swiftwasi/src	3.547s

About

Simple Web Assembly application with Go runtime and Swift binary

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages