• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This file is part of ICU4X. For terms of use, please see the file
2 // called LICENSE at the top level of the ICU4X source tree
3 // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4 
5 use criterion::{black_box, criterion_group, criterion_main, Criterion};
6 use litemap::LiteMap;
7 use std::collections::HashMap;
8 use zerotrie::ZeroTrieExtendedCapacity;
9 use zerotrie::ZeroTriePerfectHash;
10 use zerotrie::ZeroTrieSimpleAscii;
11 use zerovec::ZeroHashMap;
12 use zerovec::ZeroMap;
13 
14 mod testdata {
15     include!("../tests/data/data.rs");
16 }
17 
get_basic_bench(c: &mut Criterion)18 fn get_basic_bench(c: &mut Criterion) {
19     let mut g = c.benchmark_group("get/basic");
20 
21     // NOTE: All the trie data are the same for basic data
22     let trie = testdata::basic::TRIE_ASCII;
23     let data = testdata::basic::DATA_ASCII;
24 
25     g.bench_function("SimpleAscii", |b| {
26         let trie = ZeroTrieSimpleAscii::from_bytes(trie);
27         b.iter(|| {
28             for (key, expected) in black_box(data) {
29                 let actual = black_box(&trie).get(key);
30                 assert_eq!(Some(*expected), actual);
31             }
32         });
33     });
34 
35     g.bench_function("PerfectHash", |b| {
36         let trie = ZeroTriePerfectHash::from_bytes(trie);
37         b.iter(|| {
38             for (key, expected) in black_box(data) {
39                 let actual = black_box(&trie).get(key);
40                 assert_eq!(Some(*expected), actual);
41             }
42         });
43     });
44 
45     g.bench_function("ExtendedCapacity", |b| {
46         let trie = ZeroTrieExtendedCapacity::from_bytes(trie);
47         b.iter(|| {
48             for (key, expected) in black_box(data) {
49                 let actual = black_box(&trie).get(key);
50                 assert_eq!(Some(*expected), actual);
51             }
52         });
53     });
54 
55     g.bench_function("ZeroMap/u32", |b| {
56         let zm: ZeroMap<[u8], u32> = data.iter().map(|(a, b)| (*a, *b as u32)).collect();
57         b.iter(|| {
58             for (key, expected) in black_box(data) {
59                 let actual = black_box(&zm).get_copied(key);
60                 assert_eq!(Some(*expected as u32), actual);
61             }
62         });
63     });
64 
65     g.bench_function("ZeroMap/u8", |b| {
66         let zm: ZeroMap<[u8], u8> = data.iter().map(|(k, v)| (*k, *v as u8)).collect();
67         b.iter(|| {
68             for (key, expected) in black_box(data) {
69                 let actual = black_box(&zm).get_copied(key);
70                 assert_eq!(Some(*expected as u8), actual);
71             }
72         });
73     });
74 
75     g.bench_function("HashMap", |b| {
76         let hm: HashMap<&[u8], usize> = data.iter().copied().collect();
77         b.iter(|| {
78             for (key, expected) in black_box(data) {
79                 let actual = black_box(&hm).get(key);
80                 assert_eq!(Some(expected), actual);
81             }
82         });
83     });
84 
85     g.bench_function("ZeroHashMap/u8", |b| {
86         let zhm: ZeroHashMap<[u8], u8> = data.iter().map(|(k, v)| (*k, *v as u8)).collect();
87         b.iter(|| {
88             for (key, expected) in black_box(data) {
89                 let actual = black_box(&zhm).get(key).copied();
90                 assert_eq!(Some(*expected as u8), actual);
91             }
92         });
93     });
94 }
95 
get_subtags_bench_medium(c: &mut Criterion)96 fn get_subtags_bench_medium(c: &mut Criterion) {
97     let g = c.benchmark_group("get/subtags_10pct");
98 
99     let strings = testdata::short_subtags_10pct::STRINGS;
100     let litemap = testdata::strings_to_litemap(strings);
101 
102     get_subtags_bench_helper(g, strings, litemap);
103 }
104 
get_subtags_bench_large(c: &mut Criterion)105 fn get_subtags_bench_large(c: &mut Criterion) {
106     let g = c.benchmark_group("get/subtags_full");
107 
108     let strings = testdata::short_subtags::STRINGS;
109     let litemap = testdata::strings_to_litemap(strings);
110 
111     get_subtags_bench_helper(g, strings, litemap);
112 }
113 
get_subtags_bench_helper<M: criterion::measurement::Measurement>( mut g: criterion::BenchmarkGroup<M>, strings: &[&str], litemap: LiteMap<&[u8], usize>, )114 fn get_subtags_bench_helper<M: criterion::measurement::Measurement>(
115     mut g: criterion::BenchmarkGroup<M>,
116     strings: &[&str],
117     litemap: LiteMap<&[u8], usize>,
118 ) {
119     g.bench_function("SimpleAscii", |b| {
120         let trie = ZeroTrieSimpleAscii::try_from(&litemap).unwrap();
121         b.iter(|| {
122             for (i, key) in black_box(strings).iter().enumerate() {
123                 let actual = black_box(&trie).get(key);
124                 assert_eq!(Some(i), actual);
125             }
126         });
127     });
128 
129     g.bench_function("PerfectHash", |b| {
130         let trie = ZeroTriePerfectHash::try_from(&litemap).unwrap();
131         b.iter(|| {
132             for (i, key) in black_box(strings).iter().enumerate() {
133                 let actual = black_box(&trie).get(key);
134                 assert_eq!(Some(i), actual);
135             }
136         });
137     });
138 
139     g.bench_function("ExtendedCapacity", |b| {
140         let trie = ZeroTrieExtendedCapacity::try_from(&litemap).unwrap();
141         b.iter(|| {
142             for (i, key) in black_box(strings).iter().enumerate() {
143                 let actual = black_box(&trie).get(key);
144                 assert_eq!(Some(i), actual);
145             }
146         });
147     });
148 
149     g.bench_function("ZeroMap/u32", |b| {
150         let zm: ZeroMap<[u8], u32> = litemap.iter().map(|(a, b)| (*a, *b as u32)).collect();
151         b.iter(|| {
152             for (i, key) in black_box(strings).iter().enumerate() {
153                 let actual = black_box(&zm).get_copied(key.as_bytes());
154                 assert_eq!(Some(i as u32), actual);
155             }
156         });
157     });
158 
159     g.bench_function("ZeroMap/u8", |b| {
160         let zm: ZeroMap<[u8], u8> = litemap.iter().map(|(k, v)| (*k, *v as u8)).collect();
161         b.iter(|| {
162             for (i, key) in black_box(strings).iter().enumerate() {
163                 let actual = black_box(&zm).get_copied(key.as_bytes());
164                 assert_eq!(Some(i as u8), actual);
165             }
166         });
167     });
168 
169     g.bench_function("HashMap", |b| {
170         let hm: HashMap<&[u8], u32> = litemap.iter().map(|(a, b)| (*a, *b as u32)).collect();
171         b.iter(|| {
172             for (i, key) in black_box(strings).iter().enumerate() {
173                 let actual = black_box(&hm).get(key.as_bytes());
174                 assert_eq!(Some(i as u32), actual.copied());
175             }
176         });
177     });
178 
179     g.bench_function("ZeroHashMap/u8", |b| {
180         let zhm: ZeroHashMap<[u8], u8> = litemap.iter().map(|(k, v)| (*k, *v as u8)).collect();
181         b.iter(|| {
182             for (i, key) in black_box(strings).iter().enumerate() {
183                 let actual = black_box(&zhm).get(key.as_bytes()).copied();
184                 assert_eq!(Some(i as u8), actual);
185             }
186         });
187     });
188 
189     g.finish();
190 }
191 
192 criterion_group!(
193     benches,
194     get_basic_bench,
195     get_subtags_bench_medium,
196     get_subtags_bench_large
197 );
198 criterion_main!(benches);
199