...

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

Documentation: github.com/google/flatbuffers/tests/rust_usage_test/benches

     1// Copyright 2019 Google LLC
     2//
     3// Licensed under the Apache License, Version 2.0 (the "License");
     4// you may not use this file except in compliance with the License.
     5// You may obtain a copy of the License at
     6//
     7//     https://www.apache.org/licenses/LICENSE-2.0
     8//
     9// Unless required by applicable law or agreed to in writing, software
    10// distributed under the License is distributed on an "AS IS" BASIS,
    11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12// See the License for the specific language governing permissions and
    13// limitations under the License.
    14
    15use bencher::{benchmark_group, benchmark_main, Bencher};
    16use flexbuffers::*;
    17
    18fn push_vec_u64_to_map(b: &mut Bencher) {
    19    let va = vec![u64::max_value() - 10; 512];
    20    let vb = vec![u64::max_value() - 20; 512];
    21    let vc = vec![u64::max_value() - 30; 512];
    22    let mut n = 0;
    23
    24    b.iter(|| {
    25        let mut fxb = Builder::default();
    26        let mut m = fxb.start_map();
    27        let mut ma = m.start_vector("a");
    28        for &a in va.iter() {
    29            ma.push(a);
    30        }
    31        ma.end_vector();
    32        let mut mb = m.start_vector("b");
    33        for &b in vb.iter() {
    34            mb.push(b);
    35        }
    36        mb.end_vector();
    37        let mut mc = m.start_vector("c");
    38        for &c in vc.iter() {
    39            mc.push(c);
    40        }
    41        mc.end_vector();
    42        m.end_map();
    43        n = fxb.view().len();
    44    });
    45    b.bytes = n as u64;
    46}
    47fn push_vec_u64_to_map_reused(b: &mut Bencher) {
    48    let va = vec![u64::max_value() - 10; 512];
    49    let vb = vec![u64::max_value() - 20; 512];
    50    let vc = vec![u64::max_value() - 30; 512];
    51    let mut fxb = Builder::default();
    52    let mut n = 0;
    53    let mut go = || {
    54        let mut m = fxb.start_map();
    55        let mut ma = m.start_vector("a");
    56        for &a in va.iter() {
    57            ma.push(a);
    58        }
    59        ma.end_vector();
    60        let mut mb = m.start_vector("b");
    61        for &b in vb.iter() {
    62            mb.push(b);
    63        }
    64        mb.end_vector();
    65        let mut mc = m.start_vector("c");
    66        for &c in vc.iter() {
    67            mc.push(c);
    68        }
    69        mc.end_vector();
    70        m.end_map();
    71        n = fxb.view().len();
    72    };
    73    go(); // warm up allocations.
    74    b.iter(go);
    75    b.bytes = n as u64;
    76}
    77fn push_vec_u64_to_map_direct(b: &mut Bencher) {
    78    let va = vec![u64::max_value() - 10; 512];
    79    let vb = vec![u64::max_value() - 20; 512];
    80    let vc = vec![u64::max_value() - 30; 512];
    81    let mut n = 0;
    82
    83    b.iter(|| {
    84        let mut fxb = Builder::default();
    85        let mut m = fxb.start_map();
    86        m.push("a", &va);
    87        m.push("b", &vb);
    88        m.push("c", &vc);
    89        m.end_map();
    90        n = fxb.view().len();
    91    });
    92    b.bytes = n as u64;
    93}
    94fn push_vec_u64_to_map_direct_reused(b: &mut Bencher) {
    95    let va = vec![u64::max_value() - 10; 512];
    96    let vb = vec![u64::max_value() - 20; 512];
    97    let vc = vec![u64::max_value() - 30; 512];
    98    let mut n = 0;
    99    let mut fxb = Builder::default();
   100    let mut go = || {
   101        let mut m = fxb.start_map();
   102        m.push("a", &va);
   103        m.push("b", &vb);
   104        m.push("c", &vc);
   105        m.end_map();
   106        n = fxb.view().len();
   107    };
   108    go(); // warm up allocations.
   109    b.iter(go);
   110    b.bytes = n as u64;
   111}
   112
   113fn push_vec_without_indirect(b: &mut Bencher) {
   114    let mut builder = Builder::default();
   115    let mut n = 0;
   116    let mut go = || {
   117        let mut b = builder.start_vector();
   118        for i in 0..1024u16 {
   119            b.push(i);
   120        }
   121        b.push(i64::max_value());
   122        b.end_vector();
   123        n = builder.view().len();
   124    };
   125    go(); // warm up allocations.
   126    b.iter(go);
   127    b.bytes = n as u64;
   128}
   129// This isn't actually faster than the alternative but it is a lot smaller.
   130// Based on the above benchmarks a lot of time is stuck in the `values` stack.
   131fn push_vec_with_indirect(b: &mut Bencher) {
   132    let mut builder = Builder::default();
   133    let mut n = 0;
   134    let mut go = || {
   135        let mut b = builder.start_vector();
   136        for i in 0..1024u16 {
   137            b.push(i);
   138        }
   139        b.push(IndirectInt(i64::max_value()));
   140        b.end_vector();
   141        n = builder.view().len();
   142    };
   143    go(); // warm up allocations.
   144    b.iter(go);
   145    b.bytes = n as u64;
   146}
   147
   148fn example_map<'a>(m: &mut MapBuilder<'a>) {
   149    m.push("some_ints", &[256; 5]);
   150    m.push("some_uints", &[256u16; 5]);
   151    m.push("some_floats", &[256f32; 5]);
   152    m.push("some_strings", "muahahahahaha");
   153}
   154fn hundred_maps(b: &mut Bencher) {
   155    let mut builder = Builder::default();
   156    let mut n = 0;
   157    let mut go = || {
   158        let mut v = builder.start_vector();
   159        for _ in 0..100 {
   160            example_map(&mut v.start_map());
   161        }
   162        v.end_vector();
   163        n = builder.view().len();
   164    };
   165    go(); // Warm up allocations.
   166    b.iter(go);
   167    b.bytes = n as u64;
   168}
   169fn hundred_maps_pooled(b: &mut Bencher) {
   170    let mut builder = Builder::default();
   171    let mut n = 0;
   172    let mut go = || {
   173        let mut v = builder.start_vector();
   174        for _ in 0..100 {
   175            example_map(&mut v.start_map());
   176        }
   177        v.end_vector();
   178        n = builder.view().len();
   179    };
   180    go(); // Warm up allocations.
   181    b.iter(go);
   182    b.bytes = n as u64;
   183}
   184fn make_monster(mut monster: MapBuilder) {
   185    monster.push("type", "great orc");
   186    monster.push("age", 100u8);
   187    monster.push("name", "Mr. Orc");
   188    monster.push("coins", &[1, 25, 50, 100, 250]);
   189    monster.push("color", &[255u8, 0, 0, 0]);
   190    {
   191        let mut weapons = monster.start_vector("weapons");
   192        {
   193            let mut hammer = weapons.start_map();
   194            hammer.push("name", "hammer");
   195            hammer.push("damage type", "crush");
   196            hammer.push("damage", 20);
   197        }
   198        {
   199            let mut axe = weapons.start_map();
   200            axe.push("name", "Great Axe");
   201            axe.push("damage type", "slash");
   202            axe.push("damage", 30);
   203        }
   204    }
   205    {
   206        let mut sounds = monster.start_vector("sounds");
   207        sounds.push("grr");
   208        sounds.push("rawr");
   209        sounds.push("muahaha");
   210    }
   211}
   212fn serialize_monsters(b: &mut Bencher) {
   213    let mut builder = Builder::default();
   214    let mut n = 0;
   215    let mut go = || {
   216        let mut monsters = builder.start_vector();
   217        for _ in 0..100 {
   218            make_monster(monsters.start_map())
   219        }
   220        monsters.end_vector();
   221        n = builder.view().len();
   222    };
   223    go(); // Warm up allocations.
   224    b.iter(go);
   225    b.bytes = n as u64;
   226}
   227fn validate_monster(r: MapReader<&[u8]>) {
   228    assert_eq!(r.idx("type").as_str(), "great orc");
   229    assert_eq!(r.idx("age").as_u8(), 100);
   230    assert_eq!(r.idx("name").as_str(), "Mr. Orc");
   231    assert!(r
   232        .idx("coins")
   233        .as_vector()
   234        .iter()
   235        .map(|c| c.as_i16())
   236        .eq([1, 25, 50, 100, 250].iter().cloned()));
   237    assert!(r
   238        .idx("color")
   239        .as_vector()
   240        .iter()
   241        .map(|c| c.as_u8())
   242        .eq([255, 0, 0, 0].iter().cloned()));
   243
   244    let weapons = r.idx("weapons").as_vector();
   245    assert_eq!(weapons.len(), 2);
   246
   247    let hammer = weapons.idx(0).as_map();
   248    assert_eq!(hammer.idx("name").as_str(), "hammer");
   249    assert_eq!(hammer.idx("damage type").as_str(), "crush");
   250    assert_eq!(hammer.idx("damage").as_u64(), 20);
   251
   252    let axe = weapons.idx(1).as_map();
   253    assert_eq!(axe.idx("name").as_str(), "Great Axe");
   254    assert_eq!(axe.idx("damage type").as_str(), "slash");
   255    assert_eq!(axe.idx("damage").as_u64(), 30);
   256
   257    assert!(r
   258        .idx("sounds")
   259        .as_vector()
   260        .iter()
   261        .map(|s| s.as_str())
   262        .eq(["grr", "rawr", "muahaha"].iter().cloned()));
   263}
   264fn read_monsters(b: &mut Bencher) {
   265    let mut builder = Builder::default();
   266    let mut monsters = builder.start_vector();
   267    for _ in 0..100 {
   268        make_monster(monsters.start_map());
   269    }
   270    monsters.end_vector();
   271    b.bytes = builder.view().len() as u64;
   272    let go = || {
   273        let r = Reader::get_root(builder.view()).unwrap().as_vector();
   274        assert_eq!(r.len(), 100);
   275        for i in 0..100 {
   276            validate_monster(r.idx(i).as_map());
   277        }
   278    };
   279    b.iter(go);
   280}
   281
   282benchmark_group!(
   283    benches,
   284    push_vec_u64_to_map,
   285    push_vec_u64_to_map_reused,
   286    push_vec_u64_to_map_direct,
   287    push_vec_u64_to_map_direct_reused,
   288    push_vec_without_indirect,
   289    push_vec_with_indirect,
   290    hundred_maps,
   291    hundred_maps_pooled,
   292    serialize_monsters,
   293    read_monsters,
   294);
   295benchmark_main!(benches);

View as plain text