This project demonstrates calling Rust functions from Elixir using Erlang NIF interface. It depends on ruster_unsafe crate, a low level bindings to Erlang NIF API for Rust.
- Elixir 1.2.0 on Erlang/OTP 18.2.1 with dirty schedulers and HiPE enabled
- Rust 1.5
- Elixir 1.2.0 or newer is recommended.
- Erlang/OTP 17.0 or newer. 18.0 or newer is recommended because Elixir 1.2.0 requires 18.0.
- Rust 1.5 or newer is recommended.
These Rust functions take advantage of experimental "dirty schedulers" in Erlang/OTP 17.0 or newer, so please enable this feature.
- Erlang/OTP must be built with
--enable-dirty-schedulers
- Optionally, Erlang/OTP can be build with
--enable-hipe
, or with both--enable-hipe --enable-native-libs
First of all, clone and build the project. This will build both Rust and Elixir stuffs.
git clone https://github.com/tatsuya6502/elixir_rust_interop_demo.git
cd elixir_rust_interop_demo
iex -S mix
Try to call an Elixir function to calculate an approximate number of Pi in parallel (10 concurrent processes).
iex> :timer.tc(fn() -> Pi.calc_pi_parallel(1_000_000_000, 10) end)
{29319387, {:ok, 3.141592655589816}}
You may also try HiPE. From another terminal window, compile Pi module with hipe option.
cd elixir_rust_interop_demo
ERL_COMPILER_OPTIONS="[native, {hipe, [o3]}]" elixirc -o _build/dev/lib/elixir_rust_interop_demo/ebin/ lib/pi.ex
Then run it.
iex> l Pi
iex> :code.is_module_native(Pi)
true
iex> :timer.tc(fn() -> Pi.calc_pi_parallel(1_000_000_000, 10) end)
{15226457, {:ok, 3.141592655589816}}
Calling a Rust function from an Elixir function to calculate an approximate number of Pi in parallel (10 concurrent threads).
iex> :timer.tc(fn() -> PiNif.calc_pi_parallel(1_000_000_000, 10) end)
{1209160, {:ok, 3.141592655589816}}