...

Text file src/github.com/google/flatbuffers/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs

Documentation: github.com/google/flatbuffers/tests/rust_usage_test/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
    17use bencher::{benchmark_group, Bencher};
    18use flatbuffers;
    19
    20#[allow(dead_code, unused_imports)]
    21#[path = "../../monster_test/mod.rs"]
    22mod monster_test_generated;
    23pub use monster_test_generated::my_game;
    24
    25fn traverse_canonical_buffer(bench: &mut Bencher) {
    26    let owned_data = {
    27        let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
    28        create_serialized_example_with_generated_code(&mut builder, true);
    29        builder.finished_data().to_vec()
    30    };
    31    let data = &owned_data[..];
    32    let n = data.len() as u64;
    33    bench.iter(|| {
    34        traverse_serialized_example_with_generated_code(data);
    35    });
    36    bench.bytes = n;
    37}
    38
    39fn create_canonical_buffer_then_reset(bench: &mut Bencher) {
    40    let mut builder = &mut flatbuffers::FlatBufferBuilder::new();
    41    // warmup
    42    create_serialized_example_with_generated_code(&mut builder, true);
    43    let n = builder.finished_data().len() as u64;
    44    builder.reset();
    45
    46    bench.iter(|| {
    47        let _ = create_serialized_example_with_generated_code(&mut builder, true);
    48        builder.reset();
    49    });
    50
    51    bench.bytes = n;
    52}
    53
    54#[inline(always)]
    55fn create_serialized_example_with_generated_code(
    56    builder: &mut flatbuffers::FlatBufferBuilder,
    57    finish: bool,
    58) -> 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(
    65        builder,
    66        &my_game::example::MonsterArgs {
    67            hp: 1000,
    68            name: Some(t0_name),
    69            ..Default::default()
    70        },
    71    );
    72    let t1 = my_game::example::Monster::create(
    73        builder,
    74        &my_game::example::MonsterArgs {
    75            name: Some(t1_name),
    76            ..Default::default()
    77        },
    78    );
    79    let t2 = my_game::example::Monster::create(
    80        builder,
    81        &my_game::example::MonsterArgs {
    82            name: Some(t2_name),
    83            ..Default::default()
    84        },
    85    );
    86    let mon = {
    87        let name = builder.create_string("MyMonster");
    88        let fred_name = builder.create_string("Fred");
    89        let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4]);
    90        let test4 = builder.create_vector(&[
    91            my_game::example::Test::new(10, 20),
    92            my_game::example::Test::new(30, 40),
    93        ]);
    94        let pos = my_game::example::Vec3::new(
    95            1.0,
    96            2.0,
    97            3.0,
    98            3.0,
    99            my_game::example::Color::Green,
   100            &my_game::example::Test::new(5i16, 6i8),
   101        );
   102        let args = my_game::example::MonsterArgs {
   103            hp: 80,
   104            mana: 150,
   105            name: Some(name),
   106            pos: Some(&pos),
   107            test_type: my_game::example::Any::Monster,
   108            test: Some(
   109                my_game::example::Monster::create(
   110                    builder,
   111                    &my_game::example::MonsterArgs {
   112                        name: Some(fred_name),
   113                        ..Default::default()
   114                    },
   115                )
   116                .as_union_value(),
   117            ),
   118            inventory: Some(inventory),
   119            test4: Some(test4),
   120            testarrayofstring: Some(builder.create_vector(&[s0, s1])),
   121            testarrayoftables: Some(builder.create_vector(&[t0, t1, t2])),
   122            ..Default::default()
   123        };
   124        my_game::example::Monster::create(builder, &args)
   125    };
   126    if finish {
   127        my_game::example::finish_monster_buffer(builder, mon);
   128    }
   129
   130    builder.finished_data().len()
   131
   132    // make it do some work
   133    // if builder.finished_data().len() == 0 { panic!("bad benchmark"); }
   134}
   135
   136#[inline(always)]
   137fn blackbox<T>(t: T) -> T {
   138    // encapsulate this in case we need to turn it into a noop
   139    bencher::black_box(t)
   140}
   141
   142#[inline(always)]
   143fn traverse_serialized_example_with_generated_code(bytes: &[u8]) {
   144    let m = unsafe { my_game::example::root_as_monster_unchecked(bytes) };
   145    blackbox(m.hp());
   146    blackbox(m.mana());
   147    blackbox(m.name());
   148    let pos = m.pos().unwrap();
   149    blackbox(pos.x());
   150    blackbox(pos.y());
   151    blackbox(pos.z());
   152    blackbox(pos.test1());
   153    blackbox(pos.test2());
   154    let pos_test3 = pos.test3();
   155    blackbox(pos_test3.a());
   156    blackbox(pos_test3.b());
   157    blackbox(m.test_type());
   158    let table2 = m.test().unwrap();
   159    let monster2 = unsafe { my_game::example::Monster::init_from_table(table2) };
   160    blackbox(monster2.name());
   161    blackbox(m.inventory());
   162    blackbox(m.test4());
   163    let testarrayoftables = m.testarrayoftables().unwrap();
   164    blackbox(testarrayoftables.get(0).hp());
   165    blackbox(testarrayoftables.get(0).name());
   166    blackbox(testarrayoftables.get(1).name());
   167    blackbox(testarrayoftables.get(2).name());
   168    let testarrayofstring = m.testarrayofstring().unwrap();
   169    blackbox(testarrayofstring.get(0));
   170    blackbox(testarrayofstring.get(1));
   171}
   172
   173fn create_string_10(bench: &mut Bencher) {
   174    let builder = &mut flatbuffers::FlatBufferBuilder::with_capacity(1 << 20);
   175    let mut i = 0;
   176    bench.iter(|| {
   177        builder.create_string("foobarbaz"); // zero-terminated -> 10 bytes
   178        i += 1;
   179        if i == 10000 {
   180            builder.reset();
   181            i = 0;
   182        }
   183    });
   184
   185    bench.bytes = 10;
   186}
   187
   188fn create_string_100(bench: &mut Bencher) {
   189    let builder = &mut flatbuffers::FlatBufferBuilder::with_capacity(1 << 20);
   190    let s_owned = (0..99).map(|_| "x").collect::<String>();
   191    let s: &str = &s_owned;
   192
   193    let mut i = 0;
   194    bench.iter(|| {
   195        builder.create_string(s); // zero-terminated -> 100 bytes
   196        i += 1;
   197        if i == 1000 {
   198            builder.reset();
   199            i = 0;
   200        }
   201    });
   202
   203    bench.bytes = s.len() as u64;
   204}
   205
   206fn create_byte_vector_100_naive(bench: &mut Bencher) {
   207    let builder = &mut flatbuffers::FlatBufferBuilder::with_capacity(1 << 20);
   208    let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
   209    let v: &[u8] = &v_owned;
   210
   211    let mut i = 0;
   212    bench.iter(|| {
   213        builder.create_vector(v); // zero-terminated -> 100 bytes
   214        i += 1;
   215        if i == 10000 {
   216            builder.reset();
   217            i = 0;
   218        }
   219    });
   220
   221    bench.bytes = v.len() as u64;
   222}
   223
   224fn create_byte_vector_100_optimal(bench: &mut Bencher) {
   225    let builder = &mut flatbuffers::FlatBufferBuilder::with_capacity(1 << 20);
   226    let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
   227    let v: &[u8] = &v_owned;
   228
   229    let mut i = 0;
   230    bench.iter(|| {
   231        builder.create_vector(v);
   232        i += 1;
   233        if i == 10000 {
   234            builder.reset();
   235            i = 0;
   236        }
   237    });
   238
   239    bench.bytes = v.len() as u64;
   240}
   241
   242fn create_many_tables(bench: &mut Bencher) {
   243    let builder = &mut flatbuffers::FlatBufferBuilder::with_capacity(1 << 20);
   244    // We test vtable overhead by making many unique tables of up to 16 fields of u8s.
   245    bench.iter(|| {
   246        for i in 0..(1u16 << 10) {
   247            let t = builder.start_table();
   248            for j in 0..15 {
   249                if i & (1 << j) == 1 {
   250                    builder.push_slot_always(i * 2, 42u8);
   251                }
   252            }
   253            builder.end_table(t);
   254        }
   255        builder.reset();
   256    });
   257    bench.bytes = 1 << 15;
   258}
   259
   260benchmark_group!(
   261    benches,
   262    create_byte_vector_100_naive,
   263    create_byte_vector_100_optimal,
   264    traverse_canonical_buffer,
   265    create_canonical_buffer_then_reset,
   266    create_string_10,
   267    create_string_100,
   268    create_many_tables,
   269);

View as plain text