Skip to content

Commit e9bfca2

Browse files
emiliozbraniecki
authored andcommitted
Factor out the testing strategy (#19)
* Easier-to-profile benchmarking. * Factor out the testing strategy. And while at it don't bother creating a vec of pairs, just create a single vec for the available locales.
1 parent 3594a09 commit e9bfca2

File tree

2 files changed

+52
-141
lines changed

2 files changed

+52
-141
lines changed

benches/negotiate.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@ use criterion::Criterion;
55
use fluent_langneg::convert_vec_str_to_langids_lossy;
66
use fluent_langneg::negotiate_languages;
77

8+
use unic_langid::LanguageIdentifier;
9+
10+
#[no_mangle]
11+
#[inline(never)]
12+
fn do_negotiate<'a>(
13+
requested: &[LanguageIdentifier],
14+
available: &'a [LanguageIdentifier],
15+
) -> Vec<&'a LanguageIdentifier> {
16+
negotiate_languages(
17+
requested,
18+
available,
19+
None,
20+
fluent_langneg::NegotiationStrategy::Filtering,
21+
)
22+
}
23+
824
fn negotiate_bench(c: &mut Criterion) {
925
let requested = &["de", "it", "ru"];
1026
let available = &[
@@ -16,14 +32,7 @@ fn negotiate_bench(c: &mut Criterion) {
1632
let available = convert_vec_str_to_langids_lossy(available);
1733

1834
c.bench_function("negotiate", |b| {
19-
b.iter(|| {
20-
negotiate_languages(
21-
&requested,
22-
&available,
23-
None,
24-
fluent_langneg::NegotiationStrategy::Filtering,
25-
);
26-
})
35+
b.iter(|| do_negotiate(&requested, &available))
2736
});
2837
}
2938

src/negotiate/mod.rs

Lines changed: 35 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -140,165 +140,67 @@ pub fn filter_matches<'a, R: 'a + AsRef<LanguageIdentifier>, A: 'a + AsRef<Langu
140140
) -> Vec<&'a A> {
141141
let mut supported_locales = vec![];
142142

143-
let mut available_locales: Vec<(&LanguageIdentifier, &A)> =
144-
available.iter().map(|a| (a.as_ref(), a)).collect();
143+
let mut available_locales: Vec<&A> = available.iter().collect();
145144

146145
for req in requested {
147146
let mut req = req.as_ref().to_owned();
148147
if req.get_language() == "und" {
149148
continue;
150149
}
151150

152-
let mut match_found = false;
153-
154-
// 1) Try to find a simple (case-insensitive) string match for the request.
155-
available_locales.retain(|(key, value)| {
156-
if strategy != NegotiationStrategy::Filtering && match_found {
157-
return true;
158-
}
159-
160-
if key.matches(&req, false, false) {
161-
match_found = true;
162-
supported_locales.push(*value);
163-
return false;
164-
}
165-
true
166-
});
167-
168-
if match_found {
169-
match strategy {
170-
NegotiationStrategy::Filtering => {}
171-
NegotiationStrategy::Matching => continue,
172-
NegotiationStrategy::Lookup => break,
173-
}
151+
macro_rules! test_strategy {
152+
($self_as_range:expr, $other_as_range:expr) => {{
153+
let mut match_found = false;
154+
available_locales.retain(|locale| {
155+
if strategy != NegotiationStrategy::Filtering && match_found {
156+
return true;
157+
}
158+
159+
if locale
160+
.as_ref()
161+
.matches(&req, $self_as_range, $other_as_range)
162+
{
163+
match_found = true;
164+
supported_locales.push(*locale);
165+
return false;
166+
}
167+
true
168+
});
169+
170+
if match_found {
171+
match strategy {
172+
NegotiationStrategy::Filtering => {}
173+
NegotiationStrategy::Matching => continue,
174+
NegotiationStrategy::Lookup => break,
175+
}
176+
}
177+
}};
174178
}
175179

176-
match_found = false;
180+
// 1) Try to find a simple (case-insensitive) string match for the request.
181+
test_strategy!(false, false);
177182

178183
// 2) Try to match against the available locales treated as ranges.
179-
available_locales.retain(|(key, value)| {
180-
if strategy != NegotiationStrategy::Filtering && match_found {
181-
return true;
182-
}
183-
184-
if key.matches(&req, true, false) {
185-
match_found = true;
186-
supported_locales.push(*value);
187-
return false;
188-
}
189-
true
190-
});
191-
192-
if match_found {
193-
match strategy {
194-
NegotiationStrategy::Filtering => {}
195-
NegotiationStrategy::Matching => continue,
196-
NegotiationStrategy::Lookup => break,
197-
};
198-
}
199-
200-
match_found = false;
184+
test_strategy!(true, false);
201185

202186
// 3) Try to match against a maximized version of the requested locale
203187
if req.add_likely_subtags() {
204-
available_locales.retain(|(key, value)| {
205-
if strategy != NegotiationStrategy::Filtering && match_found {
206-
return true;
207-
}
208-
209-
if key.matches(&req, true, false) {
210-
match_found = true;
211-
supported_locales.push(*value);
212-
return false;
213-
}
214-
true
215-
});
216-
217-
if match_found {
218-
match strategy {
219-
NegotiationStrategy::Filtering => {}
220-
NegotiationStrategy::Matching => continue,
221-
NegotiationStrategy::Lookup => break,
222-
};
223-
}
224-
225-
match_found = false;
188+
test_strategy!(true, false);
226189
}
227190

228191
// 4) Try to match against a variant as a range
229192
req.clear_variants();
230-
available_locales.retain(|(key, value)| {
231-
if strategy != NegotiationStrategy::Filtering && match_found {
232-
return true;
233-
}
234-
235-
if key.matches(&req, true, true) {
236-
match_found = true;
237-
supported_locales.push(*value);
238-
return false;
239-
}
240-
true
241-
});
242-
243-
if match_found {
244-
match strategy {
245-
NegotiationStrategy::Filtering => {}
246-
NegotiationStrategy::Matching => continue,
247-
NegotiationStrategy::Lookup => break,
248-
};
249-
}
250-
251-
match_found = false;
193+
test_strategy!(true, true);
252194

253195
// 5) Try to match against the likely subtag without region
254196
req.clear_region();
255197
if req.add_likely_subtags() {
256-
available_locales.retain(|(key, value)| {
257-
if strategy != NegotiationStrategy::Filtering && match_found {
258-
return true;
259-
}
260-
261-
if key.matches(&req, true, false) {
262-
match_found = true;
263-
supported_locales.push(*value);
264-
return false;
265-
}
266-
true
267-
});
268-
269-
if match_found {
270-
match strategy {
271-
NegotiationStrategy::Filtering => {}
272-
NegotiationStrategy::Matching => continue,
273-
NegotiationStrategy::Lookup => break,
274-
};
275-
}
276-
277-
match_found = false;
198+
test_strategy!(true, false);
278199
}
279200

280201
// 6) Try to match against a region as a range
281202
req.clear_region();
282-
available_locales.retain(|(key, value)| {
283-
if strategy != NegotiationStrategy::Filtering && match_found {
284-
return true;
285-
}
286-
287-
if key.matches(&req, true, true) {
288-
match_found = true;
289-
supported_locales.push(*value);
290-
return false;
291-
}
292-
true
293-
});
294-
295-
if match_found {
296-
match strategy {
297-
NegotiationStrategy::Filtering => {}
298-
NegotiationStrategy::Matching => continue,
299-
NegotiationStrategy::Lookup => break,
300-
};
301-
}
203+
test_strategy!(true, true);
302204
}
303205

304206
supported_locales

0 commit comments

Comments
 (0)