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 #[macro_use]
18 extern crate bencher;
19 use bencher::Bencher;
20
21 extern crate flatbuffers;
22
23 #[path = "../../monster_test_generated.rs"]
24 mod monster_test_generated;
25 pub use monster_test_generated::my_game;
26
traverse_canonical_buffer(bench: &mut Bencher)27 fn traverse_canonical_buffer(bench: &mut Bencher) {
28 let owned_data = {
29 let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
30 create_serialized_example_with_generated_code(&mut builder, true);
31 builder.finished_data().to_vec()
32 };
33 let data = &owned_data[..];
34 let n = data.len() as u64;
35 bench.iter(|| {
36 traverse_serialized_example_with_generated_code(data);
37 });
38 bench.bytes = n;
39 }
40
create_canonical_buffer_then_reset(bench: &mut Bencher)41 fn create_canonical_buffer_then_reset(bench: &mut Bencher) {
42 let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
43 // warmup
44 create_serialized_example_with_generated_code(&mut builder, true);
45 let n = builder.finished_data().len() as u64;
46 builder.reset();
47
48 bench.iter(|| {
49 let _ = create_serialized_example_with_generated_code(&mut builder, true);
50 builder.reset();
51 });
52
53 bench.bytes = n;
54 }
55
56 #[inline(always)]
create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder, finish: bool) -> usize57 fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder, finish: bool) -> usize{
58 let s0 = builder.create_string("test1");
59 let s1 = builder.create_string("test2");
60 let t0_name = builder.create_string("Barney");
61 let t1_name = builder.create_string("Fred");
62 let t2_name = builder.create_string("Wilma");
63 let t0 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
64 hp: 1000,
65 name: Some(t0_name),
66 ..Default::default()
67 });
68 let t1 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
69 name: Some(t1_name),
70 ..Default::default()
71 });
72 let t2 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
73 name: Some(t2_name),
74 ..Default::default()
75 });
76 let mon = {
77 let name = builder.create_string("MyMonster");
78 let fred_name = builder.create_string("Fred");
79 let inventory = builder.create_vector_direct(&[0u8, 1, 2, 3, 4]);
80 let test4 = builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
81 my_game::example::Test::new(30, 40)]);
82 let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
83 let args = my_game::example::MonsterArgs{
84 hp: 80,
85 mana: 150,
86 name: Some(name),
87 pos: Some(&pos),
88 test_type: my_game::example::Any::Monster,
89 test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
90 name: Some(fred_name),
91 ..Default::default()
92 }).as_union_value()),
93 inventory: Some(inventory),
94 test4: Some(test4),
95 testarrayofstring: Some(builder.create_vector(&[s0, s1])),
96 testarrayoftables: Some(builder.create_vector(&[t0, t1, t2])),
97 ..Default::default()
98 };
99 my_game::example::Monster::create(builder, &args)
100 };
101 if finish {
102 my_game::example::finish_monster_buffer(builder, mon);
103 }
104
105 builder.finished_data().len()
106
107 // make it do some work
108 // if builder.finished_data().len() == 0 { panic!("bad benchmark"); }
109 }
110
111 #[inline(always)]
blackbox<T>(t: T) -> T112 fn blackbox<T>(t: T) -> T {
113 // encapsulate this in case we need to turn it into a noop
114 bencher::black_box(t)
115 }
116
117 #[inline(always)]
traverse_serialized_example_with_generated_code(bytes: &[u8])118 fn traverse_serialized_example_with_generated_code(bytes: &[u8]) {
119 let m = my_game::example::get_root_as_monster(bytes);
120 blackbox(m.hp());
121 blackbox(m.mana());
122 blackbox(m.name());
123 let pos = m.pos().unwrap();
124 blackbox(pos.x());
125 blackbox(pos.y());
126 blackbox(pos.z());
127 blackbox(pos.test1());
128 blackbox(pos.test2());
129 let pos_test3 = pos.test3();
130 blackbox(pos_test3.a());
131 blackbox(pos_test3.b());
132 blackbox(m.test_type());
133 let table2 = m.test().unwrap();
134 let monster2 = my_game::example::Monster::init_from_table(table2);
135 blackbox(monster2.name());
136 blackbox(m.inventory());
137 blackbox(m.test4());
138 let testarrayoftables = m.testarrayoftables().unwrap();
139 blackbox(testarrayoftables.get(0).hp());
140 blackbox(testarrayoftables.get(0).name());
141 blackbox(testarrayoftables.get(1).name());
142 blackbox(testarrayoftables.get(2).name());
143 let testarrayofstring = m.testarrayofstring().unwrap();
144 blackbox(testarrayofstring.get(0));
145 blackbox(testarrayofstring.get(1));
146 }
147
create_string_10(bench: &mut Bencher)148 fn create_string_10(bench: &mut Bencher) {
149 let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
150 let mut i = 0;
151 bench.iter(|| {
152 builder.create_string("foobarbaz"); // zero-terminated -> 10 bytes
153 i += 1;
154 if i == 10000 {
155 builder.reset();
156 i = 0;
157 }
158 });
159
160 bench.bytes = 10;
161 }
162
create_string_100(bench: &mut Bencher)163 fn create_string_100(bench: &mut Bencher) {
164 let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
165 let s_owned = (0..99).map(|_| "x").collect::<String>();
166 let s: &str = &s_owned;
167
168 let mut i = 0;
169 bench.iter(|| {
170 builder.create_string(s); // zero-terminated -> 100 bytes
171 i += 1;
172 if i == 1000 {
173 builder.reset();
174 i = 0;
175 }
176 });
177
178 bench.bytes = s.len() as u64;
179 }
180
create_byte_vector_100_naive(bench: &mut Bencher)181 fn create_byte_vector_100_naive(bench: &mut Bencher) {
182 let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
183 let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
184 let v: &[u8] = &v_owned;
185
186 let mut i = 0;
187 bench.iter(|| {
188 builder.create_vector(v); // zero-terminated -> 100 bytes
189 i += 1;
190 if i == 10000 {
191 builder.reset();
192 i = 0;
193 }
194 });
195
196 bench.bytes = v.len() as u64;
197 }
198
create_byte_vector_100_optimal(bench: &mut Bencher)199 fn create_byte_vector_100_optimal(bench: &mut Bencher) {
200 let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
201 let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
202 let v: &[u8] = &v_owned;
203
204 let mut i = 0;
205 bench.iter(|| {
206 builder.create_vector_direct(v);
207 i += 1;
208 if i == 10000 {
209 builder.reset();
210 i = 0;
211 }
212 });
213
214 bench.bytes = v.len() as u64;
215 }
216
217 benchmark_group!(benches, create_byte_vector_100_naive, create_byte_vector_100_optimal, traverse_canonical_buffer, create_canonical_buffer_then_reset, create_string_10, create_string_100);
218 benchmark_main!(benches);
219