Skip to content

Commit 199e48d

Browse files
authored
Add additional benchmarks (#565)
1 parent 0fb26fc commit 199e48d

File tree

4 files changed

+181
-1
lines changed

4 files changed

+181
-1
lines changed

rustler_benchmarks/lib/benchmark.ex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ defmodule Benchmark do
33

44
def nifstruct_benchmark(_input, _operation), do: error()
55
def nifrecord_benchmark(_input, _operation), do: error()
6+
def encode_tagged_enum(), do: error()
7+
def decode_tagged_enum(_), do: error()
8+
def decode_struct(_), do: error()
9+
def decode_string(_), do: error()
10+
def decode_struct_string(_), do: error()
11+
def decode_term(_), do: error()
12+
def encode_atom(), do: error()
13+
def void(), do: error()
14+
def compare_atom(_), do: error()
615

716
defp error do
817
:erlang.nif_error(:nif_not_loaded)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
defmodule Benchmark.NifVarious do
2+
@moduledoc """
3+
Benchmark the performance of decoding/encoding enums & others.
4+
"""
5+
6+
defmodule TestStruct do
7+
defstruct [:a, :b, :c, :d]
8+
end
9+
10+
defmodule TestStructString do
11+
defstruct [:a]
12+
end
13+
14+
def run do
15+
test_struct = %TestStruct{
16+
a: "abcd",
17+
b: 6_000_000_000,
18+
c: nil,
19+
d: true
20+
}
21+
22+
test_struct_string = %TestStructString{
23+
a: "abcd"
24+
}
25+
26+
test_struct_enum = {:test_struct, %TestStruct{
27+
a: "abcd",
28+
b: 6_000_000_000,
29+
c: nil,
30+
d: true
31+
}}
32+
33+
# Benchmark
34+
Benchee.run(%{
35+
"encode_atom" => fn -> Benchmark.encode_atom() end,
36+
"compare_atom" => fn -> Benchmark.compare_atom(:test) end,
37+
"void" => fn -> Benchmark.void() end,
38+
"decode_term" => fn -> Benchmark.decode_term("abcd") end,
39+
"struct_string_decode" => fn ->
40+
Benchmark.decode_struct_string(test_struct_string)
41+
end,
42+
"string_decode" => fn -> Benchmark.decode_string("abcd") end,
43+
"struct_decode" => fn -> Benchmark.decode_struct(test_struct) end,
44+
"tagged_enum_decode" => fn -> Benchmark.decode_tagged_enum(test_struct_enum) end,
45+
"tagged_enum_encode" => fn -> Benchmark.encode_tagged_enum() end
46+
})
47+
end
48+
end
Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
11
mod nif_record;
22
mod nif_struct;
3+
mod nif_various;
34

45
rustler::init!(
56
"Elixir.Benchmark",
6-
[nif_struct::benchmark, nif_record::benchmark]
7+
[
8+
nif_struct::benchmark,
9+
nif_record::benchmark,
10+
nif_various::encode_tagged_enum,
11+
nif_various::decode_tagged_enum,
12+
nif_various::decode_struct,
13+
nif_various::decode_struct_string,
14+
nif_various::decode_string,
15+
nif_various::decode_term,
16+
nif_various::void,
17+
nif_various::encode_atom,
18+
nif_various::compare_atom
19+
]
720
);
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use rustler::{atoms, Atom, NifResult, Term};
2+
use rustler::{NifStruct, NifTaggedEnum};
3+
use std::collections::HashMap;
4+
5+
atoms! {
6+
test_a,
7+
test_b,
8+
test
9+
}
10+
11+
#[derive(NifStruct)]
12+
#[module = "Benchmark.NifVarious.TestStructString"]
13+
pub struct TestStructString {
14+
a: String,
15+
}
16+
17+
#[derive(NifStruct)]
18+
#[module = "Benchmark.NifVarious.TestStruct"]
19+
pub struct TestStruct {
20+
a: String,
21+
b: i64,
22+
c: Option<String>,
23+
d: bool,
24+
}
25+
26+
#[derive(NifTaggedEnum)]
27+
pub enum TaggedEnum {
28+
UnitA,
29+
UnitB,
30+
UnitC,
31+
UnitD,
32+
UnitE,
33+
UnitF,
34+
GenericA(String),
35+
GenericB(String),
36+
GenericC(String),
37+
GenericD(String),
38+
GenericE(String),
39+
GenericF(String),
40+
GenericG(String),
41+
GenericH(String),
42+
GenericI(String),
43+
GenericJ(String),
44+
Tuple((String, i64)),
45+
List(Vec<String>),
46+
Map(HashMap<i64, String>),
47+
String(String),
48+
Int(i32),
49+
TestStruct(TestStruct),
50+
}
51+
52+
#[rustler::nif]
53+
pub fn decode_term(input: Term) -> NifResult<bool> {
54+
Ok(!input.is_atom())
55+
}
56+
57+
#[rustler::nif]
58+
pub fn decode_string(input: String) -> NifResult<bool> {
59+
Ok(!input.is_empty())
60+
}
61+
62+
#[rustler::nif]
63+
pub fn decode_struct_string(input: TestStructString) -> NifResult<bool> {
64+
Ok(!input.a.is_empty())
65+
}
66+
67+
#[rustler::nif]
68+
pub fn decode_struct(input: TestStruct) -> NifResult<bool> {
69+
Ok(input.d)
70+
}
71+
72+
#[rustler::nif]
73+
pub fn decode_tagged_enum(input: TaggedEnum) -> NifResult<bool> {
74+
match input {
75+
TaggedEnum::UnitA => Ok(true),
76+
_ => Ok(false),
77+
}
78+
}
79+
80+
#[rustler::nif]
81+
pub fn encode_tagged_enum() -> TaggedEnum {
82+
TaggedEnum::TestStruct(TestStruct {
83+
a: "abc".to_string(),
84+
b: 124,
85+
c: None,
86+
d: true,
87+
})
88+
}
89+
90+
#[rustler::nif]
91+
pub fn void() {}
92+
93+
#[rustler::nif]
94+
pub fn encode_atom() -> Atom {
95+
test_a()
96+
}
97+
98+
#[rustler::nif]
99+
pub fn compare_atom(a: Atom) -> Atom {
100+
if a == test_a() {
101+
return test_a();
102+
}
103+
if a == test_a() {
104+
return test_a();
105+
}
106+
if a == test_a() {
107+
return test_a();
108+
}
109+
a
110+
}

0 commit comments

Comments
 (0)