1 /*
2 * Copyright 2018 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 use bencher::Bencher;
18
19 #[allow(dead_code, unused_imports)]
20 #[path = "../../include_test/include_test1_generated.rs"]
21 pub mod include_test1_generated;
22
23 #[allow(dead_code, unused_imports)]
24 #[path = "../../include_test/sub/include_test2_generated.rs"]
25 pub mod include_test2_generated;
26
27 #[allow(dead_code, unused_imports)]
28 #[path = "../../monster_test_generated.rs"]
29 mod monster_test_generated;
30 pub use monster_test_generated::my_game;
31
traverse_canonical_buffer(bench: &mut Bencher)32 fn traverse_canonical_buffer(bench: &mut Bencher) {
33 let owned_data = {
34 let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
35 create_serialized_example_with_generated_code(&mut builder, true);
36 builder.finished_data().to_vec()
37 };
38 let data = &owned_data[..];
39 let n = data.len() as u64;
40 bench.iter(|| {
41 traverse_serialized_example_with_generated_code(data);
42 });
43 bench.bytes = n;
44 }
45
create_canonical_buffer_then_reset(bench: &mut Bencher)46 fn create_canonical_buffer_then_reset(bench: &mut Bencher) {
47 let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
48 // warmup
49 create_serialized_example_with_generated_code(&mut builder, true);
50 let n = builder.finished_data().len() as u64;
51 builder.reset();
52
53 bench.iter(|| {
54 let _ = create_serialized_example_with_generated_code(&mut builder, true);
55 builder.reset();
56 });
57
58 bench.bytes = n;
59 }
60
61 #[inline(always)]
create_serialized_example_with_generated_code( builder: &mut flatbuffers::FlatBufferBuilder, finish: bool, ) -> usize62 fn create_serialized_example_with_generated_code(
63 builder: &mut flatbuffers::FlatBufferBuilder,
64 finish: bool,
65 ) -> usize {
66 let s0 = builder.create_string("test1");
67 let s1 = builder.create_string("test2");
68 let t0_name = builder.create_string("Barney");
69 let t1_name = builder.create_string("Fred");
70 let t2_name = builder.create_string("Wilma");
71 let t0 = my_game::example::Monster::create(
72 builder,
73 &my_game::example::MonsterArgs {
74 hp: 1000,
75 name: Some(t0_name),
76 ..Default::default()
77 },
78 );
79 let t1 = my_game::example::Monster::create(
80 builder,
81 &my_game::example::MonsterArgs {
82 name: Some(t1_name),
83 ..Default::default()
84 },
85 );
86 let t2 = my_game::example::Monster::create(
87 builder,
88 &my_game::example::MonsterArgs {
89 name: Some(t2_name),
90 ..Default::default()
91 },
92 );
93 let mon = {
94 let name = builder.create_string("MyMonster");
95 let fred_name = builder.create_string("Fred");
96 let inventory = builder.create_vector_direct(&[0u8, 1, 2, 3, 4]);
97 let test4 = builder.create_vector_direct(&[
98 my_game::example::Test::new(10, 20),
99 my_game::example::Test::new(30, 40),
100 ]);
101 let pos = my_game::example::Vec3::new(
102 1.0,
103 2.0,
104 3.0,
105 3.0,
106 my_game::example::Color::Green,
107 &my_game::example::Test::new(5i16, 6i8),
108 );
109 let args = my_game::example::MonsterArgs {
110 hp: 80,
111 mana: 150,
112 name: Some(name),
113 pos: Some(&pos),
114 test_type: my_game::example::Any::Monster,
115 test: Some(
116 my_game::example::Monster::create(
117 builder,
118 &my_game::example::MonsterArgs {
119 name: Some(fred_name),
120 ..Default::default()
121 },
122 )
123 .as_union_value(),
124 ),
125 inventory: Some(inventory),
126 test4: Some(test4),
127 testarrayofstring: Some(builder.create_vector(&[s0, s1])),
128 testarrayoftables: Some(builder.create_vector(&[t0, t1, t2])),
129 ..Default::default()
130 };
131 my_game::example::Monster::create(builder, &args)
132 };
133 if finish {
134 my_game::example::finish_monster_buffer(builder, mon);
135 }
136
137 builder.finished_data().len()
138
139 // make it do some work
140 // if builder.finished_data().len() == 0 { panic!("bad benchmark"); }
141 }
142
143 #[inline(always)]
blackbox<T>(t: T) -> T144 fn blackbox<T>(t: T) -> T {
145 // encapsulate this in case we need to turn it into a noop
146 bencher::black_box(t)
147 }
148
149 #[inline(always)]
traverse_serialized_example_with_generated_code(bytes: &[u8])150 fn traverse_serialized_example_with_generated_code(bytes: &[u8]) {
151 let m = my_game::example::get_root_as_monster(bytes);
152 blackbox(m.hp());
153 blackbox(m.mana());
154 blackbox(m.name());
155 let pos = m.pos().unwrap();
156 blackbox(pos.x());
157 blackbox(pos.y());
158 blackbox(pos.z());
159 blackbox(pos.test1());
160 blackbox(pos.test2());
161 let pos_test3 = pos.test3();
162 blackbox(pos_test3.a());
163 blackbox(pos_test3.b());
164 blackbox(m.test_type());
165 let table2 = m.test().unwrap();
166 let monster2 = my_game::example::Monster::init_from_table(table2);
167 blackbox(monster2.name());
168 blackbox(m.inventory());
169 blackbox(m.test4());
170 let testarrayoftables = m.testarrayoftables().unwrap();
171 blackbox(testarrayoftables.get(0).hp());
172 blackbox(testarrayoftables.get(0).name());
173 blackbox(testarrayoftables.get(1).name());
174 blackbox(testarrayoftables.get(2).name());
175 let testarrayofstring = m.testarrayofstring().unwrap();
176 blackbox(testarrayofstring.get(0));
177 blackbox(testarrayofstring.get(1));
178 }
179
create_string_10(bench: &mut Bencher)180 fn create_string_10(bench: &mut Bencher) {
181 let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1 << 20);
182 let mut i = 0;
183 bench.iter(|| {
184 builder.create_string("foobarbaz"); // zero-terminated -> 10 bytes
185 i += 1;
186 if i == 10000 {
187 builder.reset();
188 i = 0;
189 }
190 });
191
192 bench.bytes = 10;
193 }
194
create_string_100(bench: &mut Bencher)195 fn create_string_100(bench: &mut Bencher) {
196 let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1 << 20);
197 let s_owned = (0..99).map(|_| "x").collect::<String>();
198 let s: &str = &s_owned;
199
200 let mut i = 0;
201 bench.iter(|| {
202 builder.create_string(s); // zero-terminated -> 100 bytes
203 i += 1;
204 if i == 1000 {
205 builder.reset();
206 i = 0;
207 }
208 });
209
210 bench.bytes = s.len() as u64;
211 }
212
create_byte_vector_100_naive(bench: &mut Bencher)213 fn create_byte_vector_100_naive(bench: &mut Bencher) {
214 let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1 << 20);
215 let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
216 let v: &[u8] = &v_owned;
217
218 let mut i = 0;
219 bench.iter(|| {
220 builder.create_vector(v); // zero-terminated -> 100 bytes
221 i += 1;
222 if i == 10000 {
223 builder.reset();
224 i = 0;
225 }
226 });
227
228 bench.bytes = v.len() as u64;
229 }
230
create_byte_vector_100_optimal(bench: &mut Bencher)231 fn create_byte_vector_100_optimal(bench: &mut Bencher) {
232 let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1 << 20);
233 let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
234 let v: &[u8] = &v_owned;
235
236 let mut i = 0;
237 bench.iter(|| {
238 builder.create_vector_direct(v);
239 i += 1;
240 if i == 10000 {
241 builder.reset();
242 i = 0;
243 }
244 });
245
246 bench.bytes = v.len() as u64;
247 }
248
249 benchmark_group!(
250 benches,
251 create_byte_vector_100_naive,
252 create_byte_vector_100_optimal,
253 traverse_canonical_buffer,
254 create_canonical_buffer_then_reset,
255 create_string_10,
256 create_string_100
257 );
258