Web Assembly (feasibility analysis): In a nutshell (WASI/WASM)

Shobhit chaturvedi
6 min readJul 18, 2023

--

There are lots of talk around web assembly since its inceptions and adoption in web and gaming industries. to check what is web assembly please check https://webassembly.org/ , it provide holistic view of web assembly ,its use cases and proposal. today we will discuss the use case of wasm in Web and Edge environment ,its performance against the existing frameworks and languages, also we will discuss the current stat of web assembly in Edge system.

Objective is to check readiness and feasibility of web assembly on edge using WASI.

Lets start the discussion , web assembly can be used in both segment edge as well as web , to make webassembly compatible with edge we have to compile it for wasm32-wasi target and in web it can be used with wasmbindgen ,lets see the difference between two variants —

wasm on Edge system Vs wasm on Web

WASMTIME

https://wasmtime.dev/

WASMEDGE

https://wasmedge.org/
https://wasmer.io/

Options to Write WASM

one can also write WASM manually using WAT (web assembly text ) scripts https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format

lets understand the difference between WASM generated from rust/c++ code and Manually created WAT file.

Now we understood what are webassembly formats and their differences now focus on WASI performance in compare to native language e.g. RUST

Performance Analysis WASI

To analyse WASM performance I developed a RUST code to read and write files into system , then generated the WASM file from rust code using wasm runtime e.g. wasm-edge or wasm-time, wasm-edge also provide further optimisation over wasm file called AOT wasm (ahead of time wasm) check https://wasmedge.org/docs/develop/build-and-run/aot/ for more details.

here is the result of files operations and we can clearly observe Rust is winner here in terms of performance as well memory requirements.

File Read operations -

File Write Operations —

CPU intensive Operations -

I also created RUST binary to calculate Fibonacci number and compare the generated wasm, also created WAT file and AOT for over all comparison, as you can see Rust is clear winner here as well in terms of performance.

Performance Analysis WASM-Webpack (Web) -

After comparing WASI/WASM on edge system now I did similar kind of experiment on web , for this I create a RUST code to calculate nth Prime Number and nth fibonacci number , convert it into WASM , package it into NPM package and imported wasm APIs using npm import on web follow https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/getting-started.html for more details.

interestingly on web JS engine is clear winner when it comes to loop intensive operations so moving to the web assembly wont provide and advantage.

But , for CPU intensive operations e.g. recursive operation , 3d rendering and game application WASM has fair advantage in terms of performance as seen in image below —

Programming Language Comparison with WASM/WASI

Now at last we will compare WASM performance against other popular programming languages e.g. C++, Rust, C# , Javascript and Python .

to run this experiment I reuse my fibonacci Rust code, and develop same login in all other programming language along with manually wat file and generated WASM from Rust.

Results are as follows —

Rust is clear winner along with C++ and C# follow the same trend in terms of performance for CPU bound operations.

Rust, C++, C# and Js are better in performance on edge system in compare to wasm.

Python on the other hand performed poorly against WASM and AOT.

After executing all above experiment we can clearly see below performance summary —

Key Findings –

  • Web assembly for web applications can be targeted first if we are seeing potential performance issues due to complex computation operations.
  • Web Assembly for standalone docker based web application can be targeted where we are seeing potential issues due to Memory bottleneck.
  • Web assembly for standalone non multithreaded python application can be targeted which involve CPU intensive operation.
  • Web assembly for standalone socket-based server application can be targeted if they are implemented in JS, Python or C# to have some performance gain.

Current State of WASM+WASI

https://github.com/WebAssembly/proposals

https://wasmedge.org/book/en/features/proposals.html

https://docs.wasmtime.dev/stability-wasi-proposals-support.html

Examples to explore with wasmedge : https://github.com/second-state/wasmedge-rustsdk-examples/

Feature which are available and ready to use in WASI

  • Support for number data types integer, floats, unsigned etc.
  • Support for file operations.
  • Multi package/includes support.
  • Portability with other languages like python, c++.

Important Feature not supported in WASI (under proposals)

  • Threads, Garbage collection, and Exceptions.
  • Passing input arguments with complex data types like struct, string, vectors are not available or limited.
  • Return values other than number types are not supported.
  • Networking, Asynch/await is not supported.

Note: wasmedge has integrated the socket ,http and database service for WASI with rust which can be used and readily available as well

Complexity in writing WAT instructions in compare to Rust code —

Sample WAT files —

(module
(func $add (param $lhs i32) (param $rhs i32) (result i32)
(
i32.add
(local.get $lhs)
(local.get $rhs)
)
)
(func $minus (param $lhs i32) (param $rhs i32) (result i32)
(
i32.sub
(local.get $lhs)
(local.get $rhs)
)
)
(export "add" (func $add))
(export "sub" (func $minus))
)

(module
(func $fib (param $n i32) (result i32)
(if (result i32)
(i32.lt_s (local.get $n)
(i32.const 2))
(then (local.get $n))
(else (i32.add (call $fib (i32.sub (local.get $n)
(i32.const 1)))
(call $fib (i32.sub (local.get $n)
(i32.const 2)))))))
(export "fib" (func $fib)))
Fibonacci code can be written in Rust and easy to understand as well --
#[no_mangle]
pub extern "C" fn fib(n:i32) -> i32 {
if n<2{
return n;
}
return fib(n-1)+fib(n-2);
}

References -

https://docs.wasmtime.dev/tutorial-create-hello-world.html

https://wasmedge.org/book/en/sdk/c.html

https://github.com/WasmEdge/WasmEdge/releases

https://ashourics.medium.com/performance-comparison-analysis-wasmer-vs-wasmtime-48c6f51b536f

https://developer.mozilla.org/en-US/docs/WebAssembly/Rust_to_wasm

https://developer.mozilla.org/en-US/docs/WebAssembly/Loading_and_running

https://rustwasm.github.io/wasm-pack/book/quickstart.html

https://medium.com/geekculture/webassembly-for-node-js-13ef6bec0a0

https://www.npmjs.com/package/@chaturvedi99/rust-web

https://github.com/WebAssembly/wabt

https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format

https://wasmedge.org/book/en/sdk/c.html

https://blog.colinbreck.com/choosing-a-webassembly-run-time/

https://wasmer.io

https://learning.oreilly.com/library/view/webassembly-the-definitive/9781492089834/ch12.html

https://learning.oreilly.com/library/view/programming-webassembly-with/9781680506846/f_0052.xhtml#d24e19821

--

--