Skip to content

Commit

Permalink
Add additional benchmarks (#565)
Browse files Browse the repository at this point in the history
  • Loading branch information
cleaton committed Mar 21, 2024
1 parent 0fb26fc commit 199e48d
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 1 deletion.
9 changes: 9 additions & 0 deletions rustler_benchmarks/lib/benchmark.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ defmodule Benchmark do

def nifstruct_benchmark(_input, _operation), do: error()
def nifrecord_benchmark(_input, _operation), do: error()
def encode_tagged_enum(), do: error()
def decode_tagged_enum(_), do: error()
def decode_struct(_), do: error()
def decode_string(_), do: error()
def decode_struct_string(_), do: error()
def decode_term(_), do: error()
def encode_atom(), do: error()
def void(), do: error()
def compare_atom(_), do: error()

defp error do
:erlang.nif_error(:nif_not_loaded)
Expand Down
48 changes: 48 additions & 0 deletions rustler_benchmarks/lib/benchmark/nif_various.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
defmodule Benchmark.NifVarious do
@moduledoc """
Benchmark the performance of decoding/encoding enums & others.
"""

defmodule TestStruct do
defstruct [:a, :b, :c, :d]
end

defmodule TestStructString do
defstruct [:a]
end

def run do
test_struct = %TestStruct{
a: "abcd",
b: 6_000_000_000,
c: nil,
d: true
}

test_struct_string = %TestStructString{
a: "abcd"
}

test_struct_enum = {:test_struct, %TestStruct{
a: "abcd",
b: 6_000_000_000,
c: nil,
d: true
}}

# Benchmark
Benchee.run(%{
"encode_atom" => fn -> Benchmark.encode_atom() end,
"compare_atom" => fn -> Benchmark.compare_atom(:test) end,
"void" => fn -> Benchmark.void() end,
"decode_term" => fn -> Benchmark.decode_term("abcd") end,
"struct_string_decode" => fn ->
Benchmark.decode_struct_string(test_struct_string)
end,
"string_decode" => fn -> Benchmark.decode_string("abcd") end,
"struct_decode" => fn -> Benchmark.decode_struct(test_struct) end,
"tagged_enum_decode" => fn -> Benchmark.decode_tagged_enum(test_struct_enum) end,
"tagged_enum_encode" => fn -> Benchmark.encode_tagged_enum() end
})
end
end
15 changes: 14 additions & 1 deletion rustler_benchmarks/native/benchmark/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
mod nif_record;
mod nif_struct;
mod nif_various;

rustler::init!(
"Elixir.Benchmark",
[nif_struct::benchmark, nif_record::benchmark]
[
nif_struct::benchmark,
nif_record::benchmark,
nif_various::encode_tagged_enum,
nif_various::decode_tagged_enum,
nif_various::decode_struct,
nif_various::decode_struct_string,
nif_various::decode_string,
nif_various::decode_term,
nif_various::void,
nif_various::encode_atom,
nif_various::compare_atom
]
);
110 changes: 110 additions & 0 deletions rustler_benchmarks/native/benchmark/src/nif_various.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use rustler::{atoms, Atom, NifResult, Term};
use rustler::{NifStruct, NifTaggedEnum};
use std::collections::HashMap;

atoms! {
test_a,
test_b,
test
}

#[derive(NifStruct)]
#[module = "Benchmark.NifVarious.TestStructString"]
pub struct TestStructString {
a: String,
}

#[derive(NifStruct)]
#[module = "Benchmark.NifVarious.TestStruct"]
pub struct TestStruct {
a: String,
b: i64,
c: Option<String>,
d: bool,
}

#[derive(NifTaggedEnum)]
pub enum TaggedEnum {
UnitA,
UnitB,
UnitC,
UnitD,
UnitE,
UnitF,
GenericA(String),
GenericB(String),
GenericC(String),
GenericD(String),
GenericE(String),
GenericF(String),
GenericG(String),
GenericH(String),
GenericI(String),
GenericJ(String),
Tuple((String, i64)),
List(Vec<String>),
Map(HashMap<i64, String>),
String(String),
Int(i32),
TestStruct(TestStruct),
}

#[rustler::nif]
pub fn decode_term(input: Term) -> NifResult<bool> {
Ok(!input.is_atom())
}

#[rustler::nif]
pub fn decode_string(input: String) -> NifResult<bool> {
Ok(!input.is_empty())
}

#[rustler::nif]
pub fn decode_struct_string(input: TestStructString) -> NifResult<bool> {
Ok(!input.a.is_empty())
}

#[rustler::nif]
pub fn decode_struct(input: TestStruct) -> NifResult<bool> {
Ok(input.d)
}

#[rustler::nif]
pub fn decode_tagged_enum(input: TaggedEnum) -> NifResult<bool> {
match input {
TaggedEnum::UnitA => Ok(true),
_ => Ok(false),
}
}

#[rustler::nif]
pub fn encode_tagged_enum() -> TaggedEnum {
TaggedEnum::TestStruct(TestStruct {
a: "abc".to_string(),
b: 124,
c: None,
d: true,
})
}

#[rustler::nif]
pub fn void() {}

#[rustler::nif]
pub fn encode_atom() -> Atom {
test_a()
}

#[rustler::nif]
pub fn compare_atom(a: Atom) -> Atom {
if a == test_a() {
return test_a();
}
if a == test_a() {
return test_a();
}
if a == test_a() {
return test_a();
}
a
}

0 comments on commit 199e48d

Please sign in to comment.