Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add additional benchmarks #565

Merged
merged 4 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}
Loading