• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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