{"id":23266786,"url":"https://github.com/ndrean/ex_zig_zigler_wasmex","last_synced_at":"2026-02-07T11:32:33.590Z","repository":{"id":268786010,"uuid":"905464925","full_name":"ndrean/ex_zig_zigler_wasmex","owner":"ndrean","description":"Demo of running Zig code in Elixir with Zigler and in WebAssembly server-side with Wasmex and client-side with native WebAssembly","archived":false,"fork":false,"pushed_at":"2024-12-19T09:37:50.000Z","size":297,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-06T07:48:57.110Z","etag":null,"topics":["elixir","wasmex","webassembly","zig","zigler"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ndrean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-18T22:08:16.000Z","updated_at":"2024-12-19T09:37:54.000Z","dependencies_parsed_at":"2024-12-18T23:20:29.782Z","dependency_job_id":"b56ebe11-3ce8-49de-8b5e-712a7d0f7a03","html_url":"https://github.com/ndrean/ex_zig_zigler_wasmex","commit_stats":null,"previous_names":["ndrean/ex_zig_zigler_wasmex"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ndrean/ex_zig_zigler_wasmex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndrean%2Fex_zig_zigler_wasmex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndrean%2Fex_zig_zigler_wasmex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndrean%2Fex_zig_zigler_wasmex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndrean%2Fex_zig_zigler_wasmex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ndrean","download_url":"https://codeload.github.com/ndrean/ex_zig_zigler_wasmex/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ndrean%2Fex_zig_zigler_wasmex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29193588,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T07:37:03.739Z","status":"ssl_error","status_checked_at":"2026-02-07T07:37:03.029Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","wasmex","webassembly","zig","zigler"],"created_at":"2024-12-19T16:21:44.213Z","updated_at":"2026-02-07T11:32:33.576Z","avatar_url":"https://github.com/ndrean.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Running Zig code in Elixir with Zigler and in Wasi-WebAssembly with Wasmex\n\nI was curious about the difference in execution time between `NIF` and `WebAssembly`.\n\n- NIF with `Zigler` server-side\n- WASI with `Wasmex` server-side\n- WASM with native `WebAssembly` in the browser\n\nAnd the winner is NIF, about two times faster.\n\nAll `Zig` code compiled `ReleaseFast` in all cases.\n\n## Compilation:\n\n- `Zigler` compiles the `Zig` for you\n- you pass the target `.wasi` in `zig build` for `WASI`\n- you pass or `.freestanding` in `zig build` for `WebAssembly`.\n\nThe main difference between the two solutions is the way you pass data to and from the host.\n\n## Receive data **into** `Elixir`:\n\n- with `Zigler`, you can receive a struct as a map. `Zigler` is quite impressive. It also provides also [resources](https://hexdocs.pm/zigler/05-resources.html#declaring-a-resource):  a (safe) way to return pointers to native data structures from a `NIF`.\n- with `Wasmex` or `WebAssembly`, you receive a memory index when the data is in binary form\n\nWhen 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. \nIt remains to pattern match on the binary on the Elixir side.\n## Pass data **from** `Elixir`:\n\n- with `Zigler`, you pass an array of data\n- with `Wasmex` or `WA`, you write data to an index that has been allocated by `Zig`. This way, you can pass strings or serialised data.\n\n## Results\n\nThe results of the Genetic Algorithm ran 32 times to collect stats back in Elixir are:\n\n### Server-side:\n\n```elixir\n# Threaded NIF\niex(24)\u003e :timer.tc(fn -\u003e GAThreaded.calc(10, \"I want a beer! What about you?!\") end)\n\n{2_624_277,\n %{max: 1733, min: 545, elitism: 10, mean: 969.25, std_dev: 467.44238906711723}}\n\n# unthreaded NIF\niex(26)\u003e :timer.tc(fn -\u003e GAStd.calc(10, \"I want a beer! What about you?!\") end)\n\n{2_038_405,\n %{max: 1926, min: 537, elitism: 10, mean: 994.46875, std_dev: 347.26}\n\n# WASI\niex(29)\u003e :timer.tc(fn -\u003e GAWasi.calc(10, \"I want a beer! What about you?!\") end)\n{4_613_034,\n %{max: 1532, min: 474, elitism: 10, mean: 894.25, std_dev: 264.93, trials: 32}}\n```\n\n### Browser:\n\n```js\n4_952_399,\n  {\n    elitism: 10,\n    mean: 1086.98,\n    stdDev: 451.45,\n    min: 428,\n    max: 2668,\n    trials: 32,\n  };\n```\n\n## Dataflow in `Javascript`.\n\nYou need to pass a string from the host (Javascript) to the WebAssembly container, and recover data from the WAC.\n\n- you call a Zig function that allocates memory of a given length\n- you populate the WA memory at this position (via an ArrayBuffer given by TextDecoder with \"ascii\" encoding)\n- you call a Zig function to read the memory at this position and populate an internal variable\n- to recover data from Zig, you need to serialise it into a linear format\n- you call a Zig function that sends you the index of this data\n- you populate a DataView at this index and convert the data\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fndrean%2Fex_zig_zigler_wasmex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fndrean%2Fex_zig_zigler_wasmex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fndrean%2Fex_zig_zigler_wasmex/lists"}