summaryrefslogtreecommitdiffstats
path: root/intl/l10n/rust/l10nregistry-rs/benches
diff options
context:
space:
mode:
Diffstat (limited to 'intl/l10n/rust/l10nregistry-rs/benches')
-rw-r--r--intl/l10n/rust/l10nregistry-rs/benches/localization.rs70
-rw-r--r--intl/l10n/rust/l10nregistry-rs/benches/preferences.rs65
-rw-r--r--intl/l10n/rust/l10nregistry-rs/benches/registry.rs133
-rw-r--r--intl/l10n/rust/l10nregistry-rs/benches/solver.rs120
-rw-r--r--intl/l10n/rust/l10nregistry-rs/benches/source.rs60
5 files changed, 448 insertions, 0 deletions
diff --git a/intl/l10n/rust/l10nregistry-rs/benches/localization.rs b/intl/l10n/rust/l10nregistry-rs/benches/localization.rs
new file mode 100644
index 0000000000..696cc244ed
--- /dev/null
+++ b/intl/l10n/rust/l10nregistry-rs/benches/localization.rs
@@ -0,0 +1,70 @@
+use criterion::criterion_group;
+use criterion::criterion_main;
+use criterion::Criterion;
+
+use fluent_bundle::FluentArgs;
+use fluent_fallback::{types::L10nKey, Localization};
+use fluent_testing::get_scenarios;
+use l10nregistry::testing::TestFileFetcher;
+
+fn preferences_bench(c: &mut Criterion) {
+ let fetcher = TestFileFetcher::new();
+
+ let mut group = c.benchmark_group("localization/scenarios");
+
+ for scenario in get_scenarios() {
+ let res_ids = scenario.res_ids.clone();
+ let l10n_keys: Vec<(String, Option<FluentArgs>)> = scenario
+ .queries
+ .iter()
+ .map(|q| {
+ (
+ q.input.id.clone(),
+ q.input.args.as_ref().map(|args| {
+ let mut result = FluentArgs::new();
+ for arg in args.as_slice() {
+ result.set(arg.id.clone(), arg.value.clone());
+ }
+ result
+ }),
+ )
+ })
+ .collect();
+
+ group.bench_function(format!("{}/format_value_sync", scenario.name), |b| {
+ b.iter(|| {
+ let (env, reg) = fetcher.get_registry_and_environment(&scenario);
+ let mut errors = vec![];
+
+ let loc = Localization::with_env(res_ids.clone(), true, env.clone(), reg.clone());
+ let bundles = loc.bundles();
+
+ for key in l10n_keys.iter() {
+ bundles.format_value_sync(&key.0, key.1.as_ref(), &mut errors);
+ }
+ })
+ });
+
+ let keys: Vec<L10nKey> = l10n_keys
+ .into_iter()
+ .map(|key| L10nKey {
+ id: key.0.into(),
+ args: key.1,
+ })
+ .collect();
+ group.bench_function(format!("{}/format_messages_sync", scenario.name), |b| {
+ b.iter(|| {
+ let (env, reg) = fetcher.get_registry_and_environment(&scenario);
+ let mut errors = vec![];
+ let loc = Localization::with_env(res_ids.clone(), true, env.clone(), reg.clone());
+ let bundles = loc.bundles();
+ bundles.format_messages_sync(&keys, &mut errors);
+ })
+ });
+ }
+
+ group.finish();
+}
+
+criterion_group!(benches, preferences_bench);
+criterion_main!(benches);
diff --git a/intl/l10n/rust/l10nregistry-rs/benches/preferences.rs b/intl/l10n/rust/l10nregistry-rs/benches/preferences.rs
new file mode 100644
index 0000000000..e4405c6537
--- /dev/null
+++ b/intl/l10n/rust/l10nregistry-rs/benches/preferences.rs
@@ -0,0 +1,65 @@
+use criterion::criterion_group;
+use criterion::criterion_main;
+use criterion::Criterion;
+
+use fluent_testing::get_scenarios;
+use l10nregistry::testing::TestFileFetcher;
+
+use unic_langid::LanguageIdentifier;
+
+fn preferences_bench(c: &mut Criterion) {
+ let fetcher = TestFileFetcher::new();
+
+ let mut group = c.benchmark_group("registry/scenarios");
+
+ for scenario in get_scenarios() {
+ let res_ids = scenario.res_ids.clone();
+
+ let locales: Vec<LanguageIdentifier> = scenario
+ .locales
+ .iter()
+ .map(|l| l.parse().unwrap())
+ .collect();
+
+ group.bench_function(format!("{}/sync/first_bundle", scenario.name), |b| {
+ b.iter(|| {
+ let reg = fetcher.get_registry(&scenario);
+ let mut bundles =
+ reg.generate_bundles_sync(locales.clone().into_iter(), res_ids.clone());
+ for _ in 0..locales.len() {
+ if bundles.next().is_some() {
+ break;
+ }
+ }
+ })
+ });
+
+ #[cfg(feature = "tokio")]
+ {
+ use futures::stream::StreamExt;
+
+ let rt = tokio::runtime::Runtime::new().unwrap();
+
+ group.bench_function(&format!("{}/async/first_bundle", scenario.name), |b| {
+ b.iter(|| {
+ rt.block_on(async {
+ let reg = fetcher.get_registry(&scenario);
+
+ let mut bundles =
+ reg.generate_bundles(locales.clone().into_iter(), res_ids.clone());
+ for _ in 0..locales.len() {
+ if bundles.next().await.is_some() {
+ break;
+ }
+ }
+ });
+ })
+ });
+ }
+ }
+
+ group.finish();
+}
+
+criterion_group!(benches, preferences_bench);
+criterion_main!(benches);
diff --git a/intl/l10n/rust/l10nregistry-rs/benches/registry.rs b/intl/l10n/rust/l10nregistry-rs/benches/registry.rs
new file mode 100644
index 0000000000..959b510943
--- /dev/null
+++ b/intl/l10n/rust/l10nregistry-rs/benches/registry.rs
@@ -0,0 +1,133 @@
+use criterion::criterion_group;
+use criterion::criterion_main;
+use criterion::Criterion;
+
+use futures::stream::StreamExt;
+use l10nregistry::source::ResourceId;
+use l10nregistry::testing::{FileSource, RegistrySetup, TestFileFetcher};
+use unic_langid::LanguageIdentifier;
+
+fn get_paths() -> Vec<ResourceId> {
+ let paths: Vec<&'static str> = vec![
+ "branding/brand.ftl",
+ "browser/sanitize.ftl",
+ "browser/preferences/blocklists.ftl",
+ "browser/preferences/colors.ftl",
+ "browser/preferences/selectBookmark.ftl",
+ "browser/preferences/connection.ftl",
+ "browser/preferences/addEngine.ftl",
+ "browser/preferences/siteDataSettings.ftl",
+ "browser/preferences/fonts.ftl",
+ "browser/preferences/languages.ftl",
+ "browser/preferences/preferences.ftl",
+ "security/certificates/certManager.ftl",
+ "security/certificates/deviceManager.ftl",
+ "toolkit/global/textActions.ftl",
+ "toolkit/printing/printUI.ftl",
+ "toolkit/updates/history.ftl",
+ "toolkit/featuregates/features.ftl",
+ ];
+
+ paths.into_iter().map(ResourceId::from).collect()
+}
+
+fn registry_bench(c: &mut Criterion) {
+ let en_us: LanguageIdentifier = "en-US".parse().unwrap();
+ let mut group = c.benchmark_group("non-metasource");
+
+ let setup = RegistrySetup::new(
+ "test",
+ vec![
+ FileSource::new("toolkit", None, vec![en_us.clone()], "toolkit/{locale}/"),
+ FileSource::new("browser", None, vec![en_us.clone()], "browser/{locale}/"),
+ FileSource::new("toolkit", None, vec![en_us.clone()], "toolkit/{locale}/"),
+ FileSource::new("browser", None, vec![en_us.clone()], "browser/{locale}/"),
+ ],
+ vec![en_us.clone()],
+ );
+ let fetcher = TestFileFetcher::new();
+ let (_, reg) = fetcher.get_registry_and_environment(setup);
+
+ group.bench_function(&format!("serial",), |b| {
+ b.iter(|| {
+ let lang_ids = vec![en_us.clone()];
+ let mut i = reg.generate_bundles_sync(lang_ids.into_iter(), get_paths());
+ while let Some(_) = i.next() {}
+ })
+ });
+
+ let rt = tokio::runtime::Runtime::new().unwrap();
+ group.bench_function(&format!("parallel",), |b| {
+ b.iter(|| {
+ let lang_ids = vec![en_us.clone()];
+ let mut i = reg.generate_bundles(lang_ids.into_iter(), get_paths());
+ rt.block_on(async { while let Some(_) = i.next().await {} });
+ })
+ });
+
+ group.finish();
+}
+
+fn registry_metasource_bench(c: &mut Criterion) {
+ let en_us: LanguageIdentifier = "en-US".parse().unwrap();
+ let mut group = c.benchmark_group("metasource");
+
+ let setup = RegistrySetup::new(
+ "test",
+ vec![
+ FileSource::new(
+ "toolkit",
+ Some("app"),
+ vec![en_us.clone()],
+ "toolkit/{locale}/",
+ ),
+ FileSource::new(
+ "browser",
+ Some("app"),
+ vec![en_us.clone()],
+ "browser/{locale}/",
+ ),
+ FileSource::new(
+ "toolkit",
+ Some("langpack"),
+ vec![en_us.clone()],
+ "toolkit/{locale}/",
+ ),
+ FileSource::new(
+ "browser",
+ Some("langpack"),
+ vec![en_us.clone()],
+ "browser/{locale}/",
+ ),
+ ],
+ vec![en_us.clone()],
+ );
+ let fetcher = TestFileFetcher::new();
+ let (_, reg) = fetcher.get_registry_and_environment(setup);
+
+ group.bench_function(&format!("serial",), |b| {
+ b.iter(|| {
+ let lang_ids = vec![en_us.clone()];
+ let mut i = reg.generate_bundles_sync(lang_ids.into_iter(), get_paths());
+ while let Some(_) = i.next() {}
+ })
+ });
+
+ let rt = tokio::runtime::Runtime::new().unwrap();
+ group.bench_function(&format!("parallel",), |b| {
+ b.iter(|| {
+ let lang_ids = vec![en_us.clone()];
+ let mut i = reg.generate_bundles(lang_ids.into_iter(), get_paths());
+ rt.block_on(async { while let Some(_) = i.next().await {} });
+ })
+ });
+
+ group.finish();
+}
+
+criterion_group!(
+ name = benches;
+ config = Criterion::default().sample_size(10);
+ targets = registry_bench, registry_metasource_bench
+);
+criterion_main!(benches);
diff --git a/intl/l10n/rust/l10nregistry-rs/benches/solver.rs b/intl/l10n/rust/l10nregistry-rs/benches/solver.rs
new file mode 100644
index 0000000000..25906fa7c0
--- /dev/null
+++ b/intl/l10n/rust/l10nregistry-rs/benches/solver.rs
@@ -0,0 +1,120 @@
+use criterion::criterion_group;
+use criterion::criterion_main;
+use criterion::Criterion;
+
+use futures::stream::Collect;
+use futures::stream::FuturesOrdered;
+use futures::StreamExt;
+use l10nregistry::solver::testing::get_scenarios;
+use l10nregistry::solver::{AsyncTester, ParallelProblemSolver, SerialProblemSolver, SyncTester};
+use std::future::Future;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+pub struct MockTester {
+ values: Vec<Vec<bool>>,
+}
+
+impl SyncTester for MockTester {
+ fn test_sync(&self, res_idx: usize, source_idx: usize) -> bool {
+ self.values[res_idx][source_idx]
+ }
+}
+
+pub struct SingleTestResult(bool);
+
+impl Future for SingleTestResult {
+ type Output = bool;
+
+ fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
+ self.0.into()
+ }
+}
+
+pub type ResourceSetStream = Collect<FuturesOrdered<SingleTestResult>, Vec<bool>>;
+pub struct TestResult(ResourceSetStream);
+
+impl std::marker::Unpin for TestResult {}
+
+impl Future for TestResult {
+ type Output = Vec<bool>;
+
+ fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ let pinned = Pin::new(&mut self.0);
+ pinned.poll(cx)
+ }
+}
+
+impl AsyncTester for MockTester {
+ type Result = TestResult;
+
+ fn test_async(&self, query: Vec<(usize, usize)>) -> Self::Result {
+ let futures = query
+ .into_iter()
+ .map(|(res_idx, source_idx)| SingleTestResult(self.test_sync(res_idx, source_idx)))
+ .collect::<Vec<_>>();
+ TestResult(futures.into_iter().collect::<FuturesOrdered<_>>().collect())
+ }
+}
+
+struct TestStream<'t> {
+ solver: ParallelProblemSolver<MockTester>,
+ tester: &'t MockTester,
+}
+
+impl<'t> TestStream<'t> {
+ pub fn new(solver: ParallelProblemSolver<MockTester>, tester: &'t MockTester) -> Self {
+ Self { solver, tester }
+ }
+}
+
+impl<'t> futures::stream::Stream for TestStream<'t> {
+ type Item = Vec<usize>;
+
+ fn poll_next(
+ mut self: std::pin::Pin<&mut Self>,
+ cx: &mut std::task::Context<'_>,
+ ) -> std::task::Poll<Option<Self::Item>> {
+ let tester = self.tester;
+ let solver = &mut self.solver;
+ let pinned = std::pin::Pin::new(solver);
+ pinned
+ .try_poll_next(cx, tester, false)
+ .map(|v| v.ok().flatten())
+ }
+}
+
+fn solver_bench(c: &mut Criterion) {
+ let scenarios = get_scenarios();
+
+ let mut group = c.benchmark_group("solver");
+
+ for scenario in scenarios {
+ let tester = MockTester {
+ values: scenario.values.clone(),
+ };
+
+ group.bench_function(&format!("serial/{}", &scenario.name), |b| {
+ b.iter(|| {
+ let mut gen = SerialProblemSolver::new(scenario.width, scenario.depth);
+ while let Ok(Some(_)) = gen.try_next(&tester, false) {}
+ })
+ });
+
+ {
+ let rt = tokio::runtime::Runtime::new().unwrap();
+
+ group.bench_function(&format!("parallel/{}", &scenario.name), |b| {
+ b.iter(|| {
+ let gen = ParallelProblemSolver::new(scenario.width, scenario.depth);
+ let mut t = TestStream::new(gen, &tester);
+ rt.block_on(async { while let Some(_) = t.next().await {} });
+ })
+ });
+ }
+ }
+ group.finish();
+}
+
+criterion_group!(benches, solver_bench);
+criterion_main!(benches);
diff --git a/intl/l10n/rust/l10nregistry-rs/benches/source.rs b/intl/l10n/rust/l10nregistry-rs/benches/source.rs
new file mode 100644
index 0000000000..35668781da
--- /dev/null
+++ b/intl/l10n/rust/l10nregistry-rs/benches/source.rs
@@ -0,0 +1,60 @@
+use criterion::criterion_group;
+use criterion::criterion_main;
+use criterion::Criterion;
+
+use fluent_testing::get_scenarios;
+use l10nregistry::testing::TestFileFetcher;
+
+use unic_langid::LanguageIdentifier;
+
+fn get_locales<S>(input: &[S]) -> Vec<LanguageIdentifier>
+where
+ S: AsRef<str>,
+{
+ input.iter().map(|s| s.as_ref().parse().unwrap()).collect()
+}
+
+fn source_bench(c: &mut Criterion) {
+ let fetcher = TestFileFetcher::new();
+
+ let mut group = c.benchmark_group("source/scenarios");
+
+ for scenario in get_scenarios() {
+ let res_ids = scenario.res_ids.clone();
+
+ let locales: Vec<LanguageIdentifier> = get_locales(&scenario.locales);
+
+ let sources: Vec<_> = scenario
+ .file_sources
+ .iter()
+ .map(|s| {
+ fetcher.get_test_file_source(&s.name, None, get_locales(&s.locales), &s.path_scheme)
+ })
+ .collect();
+
+ group.bench_function(format!("{}/has_file", scenario.name), |b| {
+ b.iter(|| {
+ for source in &sources {
+ for res_id in &res_ids {
+ source.has_file(&locales[0], &res_id);
+ }
+ }
+ })
+ });
+
+ group.bench_function(format!("{}/sync/fetch_file_sync", scenario.name), |b| {
+ b.iter(|| {
+ for source in &sources {
+ for res_id in &res_ids {
+ source.fetch_file_sync(&locales[0], &res_id, false);
+ }
+ }
+ })
+ });
+ }
+
+ group.finish();
+}
+
+criterion_group!(benches, source_bench);
+criterion_main!(benches);