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