Skip to content

Commit 0be20e3

Browse files
authored
Added Benchmark that tests serialization and deserialization of some enums. (#409)
Previous benchmarks were concerned about empty sending and empty receiving or sending bytes directly. This will now test the serialization. Signed-off-by: Narfinger <[email protected]> more enum stuff
1 parent 64e76e5 commit 0be20e3

File tree

3 files changed

+197
-0
lines changed

3 files changed

+197
-0
lines changed

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ harness = false
2323
name = "ipc_shared_mem"
2424
harness = false
2525

26+
[[bench]]
27+
name = "struct_ipc"
28+
harness = false
29+
2630
[features]
2731
default = []
2832
force-inprocess = []
@@ -52,6 +56,7 @@ crossbeam-utils = "0.8"
5256
futures-test = "0.3"
5357
static_assertions = "1.1.0"
5458
criterion = { version = "0.5", features = ["html_reports"] }
59+
rand = "0.9.2"
5560

5661
[target.'cfg(target_os = "windows")'.dependencies.windows]
5762
version = "0.61"

benches/ipc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,5 @@ criterion_group!(
7070
transfer_receivers<8>,
7171
transfer_receivers<64>,
7272
);
73+
7374
criterion_main!(benches);

benches/struct_ipc.rs

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
use criterion::{criterion_group, criterion_main, Criterion};
2+
use ipc_channel::ipc;
3+
use rand::prelude::*;
4+
use serde::{Deserialize, Serialize};
5+
6+
#[derive(Clone, Serialize, Deserialize)]
7+
enum TestSmall {
8+
Msg0,
9+
Msg1,
10+
Msg2(u32, u32),
11+
Msg3(u32, u32, u32),
12+
Msg4(String),
13+
Msg5,
14+
Msg6,
15+
}
16+
17+
trait NewFromRandom {
18+
fn new(rng: &mut ThreadRng) -> Self;
19+
}
20+
21+
impl NewFromRandom for TestSmall {
22+
fn new(rng: &mut ThreadRng) -> Self {
23+
match rng.random_range(0..=6) {
24+
0 => Self::Msg0,
25+
1 => Self::Msg1,
26+
2 => Self::Msg2(23, 42),
27+
3 => Self::Msg3(23, 42, 243),
28+
4 => Self::Msg4(String::from("This is a test string of medium size")),
29+
5 => Self::Msg5,
30+
6 => Self::Msg6,
31+
_ => Self::Msg6,
32+
}
33+
}
34+
}
35+
36+
#[derive(Clone, Serialize, Deserialize)]
37+
enum TestMedium {
38+
Msg0(u32),
39+
Msg1(u32),
40+
Msg2(u32),
41+
Msg3(u32),
42+
Msg4(u32),
43+
Msg5(u32),
44+
Msg6(u32),
45+
Msg7(u32),
46+
Msg8(u32),
47+
Msg9(u32),
48+
Msg10(u32),
49+
Msg11(u32),
50+
Msg12(u32),
51+
Msg13(u32),
52+
Msg14(u32),
53+
Msg15(u32),
54+
Msg16(u32),
55+
Msg17(u32),
56+
Msg18(u32),
57+
Msg19(u32),
58+
Msg20(u32),
59+
Msg21(u32),
60+
Msg22(u32),
61+
Msg23(u32),
62+
Msg24(u32),
63+
Msg25(u32),
64+
Msg26(u32),
65+
}
66+
67+
impl NewFromRandom for TestMedium {
68+
fn new(rng: &mut ThreadRng) -> Self {
69+
match rng.random_range(0..=26) {
70+
0 => Self::Msg0(42),
71+
1 => Self::Msg1(42),
72+
2 => Self::Msg2(42),
73+
3 => Self::Msg3(42),
74+
4 => Self::Msg4(42),
75+
5 => Self::Msg5(42),
76+
6 => Self::Msg6(42),
77+
7 => Self::Msg7(42),
78+
8 => Self::Msg8(42),
79+
9 => Self::Msg9(42),
80+
10 => Self::Msg10(42),
81+
11 => Self::Msg11(42),
82+
12 => Self::Msg12(42),
83+
13 => Self::Msg13(42),
84+
14 => Self::Msg14(42),
85+
15 => Self::Msg15(42),
86+
16 => Self::Msg16(42),
87+
17 => Self::Msg17(42),
88+
18 => Self::Msg18(42),
89+
19 => Self::Msg19(42),
90+
20 => Self::Msg20(42),
91+
21 => Self::Msg21(42),
92+
22 => Self::Msg22(42),
93+
23 => Self::Msg23(42),
94+
24 => Self::Msg24(42),
95+
25 => Self::Msg25(42),
96+
26 => Self::Msg26(42),
97+
_ => Self::Msg6(42),
98+
}
99+
}
100+
}
101+
102+
#[derive(Serialize, Deserialize)]
103+
enum TestFractured {
104+
Msg0,
105+
Msg1(Vec<usize>),
106+
Msg2(
107+
usize,
108+
usize,
109+
usize,
110+
usize,
111+
usize,
112+
usize,
113+
usize,
114+
usize,
115+
usize,
116+
usize,
117+
),
118+
Msg3(usize),
119+
Msg4(usize, usize, usize),
120+
}
121+
122+
impl NewFromRandom for TestFractured {
123+
fn new(rng: &mut ThreadRng) -> Self {
124+
match rng.random_range(0..=4) {
125+
0 => Self::Msg0,
126+
1 => Self::Msg1(vec![1, 2, 3]),
127+
2 => Self::Msg2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
128+
3 => Self::Msg3(1),
129+
4 => Self::Msg4(1, 2, 3),
130+
_ => Self::Msg3(1),
131+
}
132+
}
133+
}
134+
135+
#[derive(Serialize, Deserialize)]
136+
enum TestNested {
137+
Msg0,
138+
Msg1(TestSmall),
139+
Msg2(TestMedium),
140+
Msg3(TestFractured),
141+
Msg4(usize),
142+
}
143+
144+
impl NewFromRandom for TestNested {
145+
fn new(rng: &mut ThreadRng) -> Self {
146+
match rng.random_range(0..=5) {
147+
0 => Self::Msg0,
148+
1 => Self::Msg1(TestSmall::Msg6),
149+
2 => Self::Msg2(TestMedium::Msg20(2)),
150+
3 => Self::Msg3(TestFractured::Msg3(0)),
151+
4 => Self::Msg4(2),
152+
_ => Self::Msg3(TestFractured::Msg0),
153+
}
154+
}
155+
}
156+
157+
fn transfer_enum<T>(criterion: &mut Criterion)
158+
where
159+
T: NewFromRandom,
160+
T: for<'de> Deserialize<'de>,
161+
T: Serialize,
162+
{
163+
criterion.bench_function("transfer_simple_struct", |bencher| {
164+
let (tx, rx) = ipc::channel().unwrap();
165+
let mut rng = rand::rng();
166+
167+
bencher.iter_batched(
168+
|| T::new(&mut rng),
169+
|s| {
170+
tx.send(s).unwrap();
171+
rx.recv().unwrap();
172+
},
173+
criterion::BatchSize::SmallInput,
174+
);
175+
});
176+
}
177+
178+
// TestSmall is a small enum
179+
// TestMedium is a medium size enum
180+
// TestFractured is an enum with varying sizes of inners
181+
// TestNested nests the enums
182+
183+
criterion_group!(
184+
benches,
185+
transfer_enum<TestSmall>,
186+
transfer_enum<TestMedium>,
187+
transfer_enum<TestFractured>,
188+
transfer_enum<TestNested>,
189+
);
190+
191+
criterion_main!(benches);

0 commit comments

Comments
 (0)