Home | History | Annotate | Download | only in benches
      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 
     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 
     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)]
     57 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)]
    112 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)]
    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 
    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 
    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 
    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 
    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