diff --git a/Cargo.lock b/Cargo.lock index 036a78f36e..9101913365 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1467,8 +1467,12 @@ version = "1.4.0" dependencies = [ "criterion", "icu_datagen", + "icu_datetime", + "icu_datetime_data", "icu_locid", + "icu_locid_transform", "icu_provider", + "icu_provider_adapters", "log", "postcard", "serde", diff --git a/provider/blob/Cargo.toml b/provider/blob/Cargo.toml index 90891233e3..943b1a8962 100644 --- a/provider/blob/Cargo.toml +++ b/provider/blob/Cargo.toml @@ -31,7 +31,11 @@ log = { workspace = true, optional = true } [dev-dependencies] icu_locid = { path = "../../components/locid", default-features = false, features = ["serde"] } +icu_datetime = { path = "../../components/datetime", default-features = false, features = ["datagen", "experimental"] } +icu_datetime_data = { path = "../../provider/baked/datetime" } +icu_locid_transform = { path = "../../components/locid_transform", default-features = false, features = ["compiled_data"] } icu_datagen = { path = "../../provider/datagen", default-features = false } +icu_provider_adapters = { path = "../../provider/adapters", default-features = false } twox-hash = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] @@ -53,6 +57,11 @@ export = [ [lib] bench = false # This option is required for Benchmark CI +[[bench]] +name = "auxkey_bench" +harness = false +required-features = ["export"] + [[bench]] name = "blob_version_bench" harness = false diff --git a/provider/blob/benches/auxkey_bench.rs b/provider/blob/benches/auxkey_bench.rs new file mode 100644 index 0000000000..8167fde760 --- /dev/null +++ b/provider/blob/benches/auxkey_bench.rs @@ -0,0 +1,158 @@ +// This file is part of ICU4X. For terms of use, please see the file +// called LICENSE at the top level of the ICU4X source tree +// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +// TODO(review): write macro in a way that doesn't raise this warning +#![allow(semicolon_in_expressions_from_macros)] + +extern crate alloc; + +use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use icu_datagen::prelude::*; +use icu_datetime::provider::neo::*; +use icu_locid_transform::LocaleFallbacker; +use icu_provider::prelude::*; +use icu_provider_adapters::fallback::LocaleFallbackProvider; +use icu_provider_blob::export::BlobExporter; +use icu_provider_blob::BlobDataProvider; + +struct Baked; + +const _: () = { + pub mod icu { + pub use icu_datetime as datetime; + pub use icu_locid_transform as locid_transform; + } + icu_datetime_data::make_provider!(Baked); + + icu_datetime_data::impl_datetime_patterns_buddhist_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_chinese_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_coptic_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_dangi_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_ethiopic_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_gregory_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_hebrew_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_indian_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_islamic_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_japanese_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_japanext_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_persian_skeleton_v1!(Baked); + icu_datetime_data::impl_datetime_patterns_roc_skeleton_v1!(Baked); + + icu_datetime_data::impliterable_datetime_patterns_buddhist_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_chinese_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_coptic_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_dangi_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_ethiopic_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_gregory_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_hebrew_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_indian_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_islamic_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_japanese_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_japanext_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_persian_skeleton_v1!(Baked); + icu_datetime_data::impliterable_datetime_patterns_roc_skeleton_v1!(Baked); +}; + +macro_rules! skeleton_markers { + ($cb:ident) => { + $cb!([ + BuddhistDateNeoSkeletonPatternsV1Marker, + ChineseDateNeoSkeletonPatternsV1Marker, + CopticDateNeoSkeletonPatternsV1Marker, + DangiDateNeoSkeletonPatternsV1Marker, + EthiopianDateNeoSkeletonPatternsV1Marker, + GregorianDateNeoSkeletonPatternsV1Marker, + HebrewDateNeoSkeletonPatternsV1Marker, + IndianDateNeoSkeletonPatternsV1Marker, + IslamicDateNeoSkeletonPatternsV1Marker, + JapaneseDateNeoSkeletonPatternsV1Marker, + JapaneseExtendedDateNeoSkeletonPatternsV1Marker, + PersianDateNeoSkeletonPatternsV1Marker, + RocDateNeoSkeletonPatternsV1Marker, + ]); + }; +} + +macro_rules! make_exportable_provider_cb { + ([$($marker:path,)+]) => { + icu_provider::make_exportable_provider!(Baked, [$($marker,)+]); + }; +} + +macro_rules! key_array_cb { + ([$($marker:path,)+]) => { + [$(<$marker>::KEY,)+] + }; +} + +skeleton_markers!(make_exportable_provider_cb); + +fn make_blob_v1() -> Vec { + let mut blob: Vec = Vec::new(); + let exporter = BlobExporter::new_with_sink(Box::new(&mut blob)); + DatagenDriver::new() + .with_keys(skeleton_markers!(key_array_cb)) + .with_locales_and_fallback([LocaleFamily::FULL], Default::default()) + .export(&Baked, exporter) + .unwrap(); + assert_eq!(blob.len(), 567405); + assert!(blob.len() > 100); + blob +} + +fn make_blob_v2() -> Vec { + let mut blob: Vec = Vec::new(); + let exporter = BlobExporter::new_v2_with_sink(Box::new(&mut blob)); + DatagenDriver::new() + .with_keys(skeleton_markers!(key_array_cb)) + .with_locales_and_fallback([LocaleFamily::FULL], Default::default()) + .export(&Baked, exporter) + .unwrap(); + assert_eq!(blob.len(), 218376); + assert!(blob.len() > 100); + blob +} + +fn auxkey_bench(c: &mut Criterion) { + let blob_v1 = make_blob_v1(); + auxkey_bench_for_version(c, &blob_v1, "v1"); + let blob_v2 = make_blob_v2(); + auxkey_bench_for_version(c, &blob_v2, "v2"); +} + +fn auxkey_bench_for_version(c: &mut Criterion, blob: &[u8], version_id: &str) { + c.bench_function(&format!("provider/auxkey/construct/{version_id}"), |b| { + b.iter(|| BlobDataProvider::try_new_from_blob(black_box(blob).into()).unwrap()); + }); + + let provider = LocaleFallbackProvider::new_with_fallbacker( + BlobDataProvider::try_new_from_blob(black_box(blob).into()).unwrap(), + LocaleFallbacker::new().static_to_owned(), + ); + + for locale_str in ["sr-Latn-x-ym0d", "sr-ME-x-ym0d"] { + let locale = locale_str.parse::().unwrap(); + + c.bench_function( + &format!("provider/auxkey/fallback/{locale_str}/{version_id}"), + |b| { + b.iter(|| { + assert!( + DataProvider::::load( + &provider.as_deserializing(), + DataRequest { + locale: black_box(&locale), + metadata: Default::default() + } + ) + .is_ok() + ) + }); + }, + ); + } +} + +criterion_group!(benches, auxkey_bench,); +criterion_main!(benches);