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