ndrean/ex_zig_zigler_wasmex
Demo of running Zig code in Elixir with Zigler and in WebAssembly server-side with Wasmex and client-side with native WebAssembly
I was curious about the difference in execution time between NIF
and WebAssembly
.
Zigler
server-sideWasmex
server-sideWebAssembly
in the browserAnd the winner is NIF, about two times faster.
All Zig
code compiled ReleaseFast
in all cases.
Zigler
compiles the Zig
for you.wasi
in zig build
for WASI
.freestanding
in zig build
for WebAssembly
.The main difference between the two solutions is the way you pass data to and from the host.
Elixir
:Zigler
, you can receive a struct as a map. Zigler
is quite impressive. It also provides also resources: a (safe) way to return pointers to native data structures from a NIF
.Wasmex
or WebAssembly
, you receive a memory index when the data is in binary formWhen using WebAssembly, the crux of the interaction is the serialisation of the data structure in Zig you want to pass to Elixir in order to fit the linear memory model. It remains to pattern match on the binary on the Elixir side.
Elixir
:Zigler
, you pass an array of dataWasmex
or WA
, you write data to an index that has been allocated by Zig
. This way, you can pass strings or serialised data.The results of the Genetic Algorithm ran 32 times to collect stats back in Elixir are:
# Threaded NIF
iex(24)> :timer.tc(fn -> GAThreaded.calc(10, "I want a beer! What about you?!") end)
{2_624_277,
%{max: 1733, min: 545, elitism: 10, mean: 969.25, std_dev: 467.44238906711723}}
# unthreaded NIF
iex(26)> :timer.tc(fn -> GAStd.calc(10, "I want a beer! What about you?!") end)
{2_038_405,
%{max: 1926, min: 537, elitism: 10, mean: 994.46875, std_dev: 347.26}
# WASI
iex(29)> :timer.tc(fn -> GAWasi.calc(10, "I want a beer! What about you?!") end)
{4_613_034,
%{max: 1532, min: 474, elitism: 10, mean: 894.25, std_dev: 264.93, trials: 32}}
4_952_399,
{
elitism: 10,
mean: 1086.98,
stdDev: 451.45,
min: 428,
max: 2668,
trials: 32,
};
Javascript
.You need to pass a string from the host (Javascript) to the WebAssembly container, and recover data from the WAC.