complex_bench/
complex_bench.rs1#![allow(dead_code)]
2
3extern crate syncpool;
4
5use std::collections::HashMap;
6use std::sync::mpsc;
7use std::thread;
8use std::time::{Duration, Instant};
9use syncpool::prelude::*;
10
11const TRIAL_RUNS: usize = 64;
12const TEST_SIZE: usize = 128;
13const BUF_CAP: usize = 1024;
14const BUSY_PERIOD: u64 = 16;
15const DENOMINATOR: usize = 1;
16const ASYNC_MODE: bool = true;
17
18type TestStruct = Buffer;
19static mut POOL: Option<SyncPool<TestStruct>> = None;
20
21struct Buffer {
23 id: usize,
24 buf: [u8; BUF_CAP],
25}
26
27impl Buffer {
28 fn len(&self) -> usize {
29 self.buf.len()
30 }
31}
32
33impl Default for Buffer {
34 fn default() -> Self {
35 let mut base = Buffer {
36 id: 0,
37 buf: [0u8; BUF_CAP],
38 };
39
40 base.buf[42] = 42;
43 base
44 }
45}
46
47#[derive(Default, Debug)]
48struct ComplexStruct {
49 id: usize,
50 name: String,
51 body: Vec<String>,
52 flags: Vec<usize>,
53 children: Vec<usize>,
54 index: HashMap<usize, String>,
55 rev_index: HashMap<String, usize>,
56}
57
58fn main() {
59 pool_setup();
60
61 let async_mode = ASYNC_MODE;
62 let trials = TRIAL_RUNS;
63 let mut sum = 0;
64
65 println!("Init len: {}", unsafe { POOL.as_ref().unwrap().len() });
66
67 for i in 0..trials {
68 let res = if async_mode {
69 let n = thread::spawn(|| run(true));
70 let p = thread::spawn(|| run(false));
71
72 let p_time = p.join().unwrap_or_default() as i128;
73 let n_time = n.join().unwrap_or_default() as i128;
74
75 n_time - p_time
76 } else {
77 let n_time = run(true) as i128;
78 let p_time = run(false) as i128;
79
80 n_time - p_time
81 };
82
83 sum += res;
84
85 println!(">>> Trial: {}; Advance: {} us <<<", i, res);
86 }
88
89 println!("Remainder len: {}", unsafe { POOL.as_ref().unwrap().len() });
90
91 println!(
92 "\nAverage: {} ms\n",
93 (sum as f64) / (trials as f64) / 1000f64
94 );
95}
96
97fn pool_setup() {
98 unsafe {
99 let mut pool = SyncPool::with_size(128);
100
101 pool.reset_handle(sanitizer);
104
105 POOL.replace(pool);
118 }
119}
120
121fn sanitizer(data: &mut TestStruct) {
122 data.id = 21;
123}
124
125fn run(alloc: bool) -> u128 {
126 let (tx, rx) = mpsc::sync_channel(32);
127 let tx_clone = tx.clone();
128
129 let now = Instant::now();
130
131 let send_one = thread::spawn(move || {
132 for i in 0..TEST_SIZE {
133 if i % DENOMINATOR == 0 {
134 thread::sleep(Duration::from_nanos(BUSY_PERIOD));
135 }
136
137 let mut data = if alloc {
138 Default::default()
139 } else {
140 unsafe { POOL.as_mut().unwrap().get() }
141 };
142
143 assert!(data.id == 21 || data.id == 0, "Wrong id: {}", data.id);
144 assert_ne!(data.id, 42);
145 data.id = 42;
146
147 tx_clone.try_send(data).unwrap_or_default();
151 }
152
153 });
155
156 let send_two = thread::spawn(move || {
157 for i in 0..TEST_SIZE {
158 if i % DENOMINATOR == 0 {
159 thread::sleep(Duration::from_nanos(BUSY_PERIOD));
160 }
161
162 let mut data = if alloc {
163 Default::default()
164 } else {
165 unsafe { POOL.as_mut().unwrap().get() }
166 };
167
168 assert!(data.id == 21 || data.id == 0, "Wrong id: {}", data.id);
169 assert_ne!(data.id, 42);
170 data.id = 42;
171
172 tx.try_send(data).unwrap_or_default();
176 }
177
178 });
180
181 let recv_one = thread::spawn(move || {
182 thread::sleep(Duration::from_micros(5));
183
184 while let Ok(arr) = rx.recv() {
185 if !alloc {
188 unsafe {
189 POOL.as_mut().unwrap().put(arr);
190 }
191 }
192 }
193
194 });
196
197 for i in 0..TEST_SIZE {
198 if i % DENOMINATOR == 1 {
200 thread::sleep(Duration::from_nanos(BUSY_PERIOD));
201 }
202
203 let mut data = if alloc {
204 Default::default()
205 } else {
206 unsafe { POOL.as_mut().unwrap().get() }
207 };
208
209 assert_ne!(data.id, 42);
211 data.id = 42;
212
213 if !alloc {
217 unsafe { POOL.as_mut().unwrap().put(data) };
219 }
220 }
221
222 send_one.join().unwrap_or_default();
225 send_two.join().unwrap_or_default();
226 recv_one.join().unwrap_or_default();
227
228 now.elapsed().as_micros()
229}