|
| 1 | +use criterion::criterion_group; |
| 2 | +use criterion::criterion_main; |
| 3 | +use criterion::Criterion; |
| 4 | +use criterion::{Bencher, BenchmarkId}; |
| 5 | +use icu_calendar::DateTime; |
| 6 | +use icu_datetime::{options::length::Time, TimeFormatter}; |
| 7 | +use icu_locid::LanguageIdentifier; |
| 8 | +use intl_memoizer::{IntlLangMemoizer, Memoizable}; |
| 9 | + |
| 10 | +struct TF(pub TimeFormatter); |
| 11 | + |
| 12 | +use icu_provider_blob::BlobDataProvider; |
| 13 | +const ICU4X_DATA: &[u8] = include_bytes!(concat!( |
| 14 | + "/Users/zibi/projects/icu-perf/data/icu4x-1.4-datetime.postcard" |
| 15 | +)); |
| 16 | + |
| 17 | +impl Memoizable for TF { |
| 18 | + type Args = (Time,); |
| 19 | + |
| 20 | + type Provider = icu_provider_blob::BlobDataProvider; |
| 21 | + |
| 22 | + /// If the construtor is fallible, than errors can be described here. |
| 23 | + type Error = (); |
| 24 | + |
| 25 | + /// This function wires together the `Args` and `Error` type to construct |
| 26 | + /// the intl API. In our example, there is |
| 27 | + fn construct( |
| 28 | + lang: LanguageIdentifier, |
| 29 | + args: Self::Args, |
| 30 | + provider: Option<&Self::Provider>, |
| 31 | + ) -> Result<Self, Self::Error> { |
| 32 | + Ok(Self( |
| 33 | + TimeFormatter::try_new_with_length_with_buffer_provider( |
| 34 | + provider.unwrap(), |
| 35 | + &lang.into(), |
| 36 | + args.0, |
| 37 | + ) |
| 38 | + .unwrap(), |
| 39 | + )) |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +const SETS: usize = 10; |
| 44 | +const REPS: usize = 10; |
| 45 | + |
| 46 | +fn construct_lang_bench(c: &mut Criterion) { |
| 47 | + let lang: LanguageIdentifier = "en-US".parse().unwrap(); |
| 48 | + let provider = |
| 49 | + BlobDataProvider::try_new_from_static_blob(ICU4X_DATA).expect("Failed to load data"); |
| 50 | + |
| 51 | + c.bench_with_input( |
| 52 | + BenchmarkId::new("construct_lang", &lang), |
| 53 | + &(lang, provider), |
| 54 | + |b, (lang, provider)| { |
| 55 | + b.iter(|| { |
| 56 | + let _ = IntlLangMemoizer::new(lang.clone(), Some(provider)); |
| 57 | + }); |
| 58 | + }, |
| 59 | + ); |
| 60 | +} |
| 61 | + |
| 62 | +fn populate_lang(c: &mut Criterion) { |
| 63 | + let lang: LanguageIdentifier = "en".parse().unwrap(); |
| 64 | + |
| 65 | + let input = DateTime::try_new_gregorian_datetime(2020, 9, 1, 12, 34, 28).unwrap(); |
| 66 | + let provider = |
| 67 | + BlobDataProvider::try_new_from_static_blob(ICU4X_DATA).expect("Failed to load data"); |
| 68 | + let construct_args = (Time::Short,); |
| 69 | + |
| 70 | + c.bench_with_input( |
| 71 | + BenchmarkId::new("populate_lang", &lang), |
| 72 | + &(construct_args, provider), |
| 73 | + |b: &mut Bencher, (construct_args, provider)| { |
| 74 | + b.iter(|| { |
| 75 | + let memoizer = IntlLangMemoizer::new(lang.clone(), Some(provider)); |
| 76 | + for _ in 0..SETS { |
| 77 | + for _ in 0..REPS { |
| 78 | + let _ = memoizer.with_try_get::<TF, _, _>(construct_args, |intl_example| { |
| 79 | + intl_example.0.format_to_string(&input) |
| 80 | + }); |
| 81 | + } |
| 82 | + } |
| 83 | + }); |
| 84 | + }, |
| 85 | + ); |
| 86 | +} |
| 87 | + |
| 88 | +fn without_memoizer(c: &mut Criterion) { |
| 89 | + let lang: LanguageIdentifier = "en".parse().unwrap(); |
| 90 | + let provider = |
| 91 | + BlobDataProvider::try_new_from_static_blob(ICU4X_DATA).expect("Failed to load data"); |
| 92 | + let construct_args = (Time::Short,); |
| 93 | + |
| 94 | + let input = DateTime::try_new_gregorian_datetime(2020, 9, 1, 12, 34, 28).unwrap(); |
| 95 | + |
| 96 | + c.bench_with_input( |
| 97 | + BenchmarkId::new("without_memoizer", &lang), |
| 98 | + &(construct_args, provider), |
| 99 | + |b: &mut Bencher, (construct_args, provider)| { |
| 100 | + b.iter(|| { |
| 101 | + for _ in 0..SETS { |
| 102 | + for _ in 0..REPS { |
| 103 | + let formatter = TimeFormatter::try_new_with_length_with_buffer_provider( |
| 104 | + provider, |
| 105 | + &lang.clone().into(), |
| 106 | + construct_args.0, |
| 107 | + ) |
| 108 | + .unwrap(); |
| 109 | + let _ = formatter.format(&input); |
| 110 | + } |
| 111 | + } |
| 112 | + }); |
| 113 | + }, |
| 114 | + ); |
| 115 | +} |
| 116 | + |
| 117 | +fn without_memoizer_hoisted(c: &mut Criterion) { |
| 118 | + let lang: LanguageIdentifier = "en".parse().unwrap(); |
| 119 | + let provider = |
| 120 | + BlobDataProvider::try_new_from_static_blob(ICU4X_DATA).expect("Failed to load data"); |
| 121 | + let construct_args = (Time::Short,); |
| 122 | + |
| 123 | + let input = DateTime::try_new_gregorian_datetime(2020, 9, 1, 12, 34, 28).unwrap(); |
| 124 | + |
| 125 | + c.bench_with_input( |
| 126 | + BenchmarkId::new("without_memoizer_hoisted", &lang), |
| 127 | + &(construct_args, provider), |
| 128 | + |b: &mut Bencher, (construct_args, provider)| { |
| 129 | + b.iter(|| { |
| 130 | + for _ in 0..SETS { |
| 131 | + let formatter = TimeFormatter::try_new_with_length_with_buffer_provider( |
| 132 | + provider, |
| 133 | + &lang.clone().into(), |
| 134 | + construct_args.0, |
| 135 | + ) |
| 136 | + .unwrap(); |
| 137 | + for _ in 0..REPS { |
| 138 | + let _ = formatter.format(&input); |
| 139 | + } |
| 140 | + } |
| 141 | + }); |
| 142 | + }, |
| 143 | + ); |
| 144 | +} |
| 145 | + |
| 146 | +criterion_group!( |
| 147 | + benches, |
| 148 | + construct_lang_bench, |
| 149 | + populate_lang, |
| 150 | + without_memoizer, |
| 151 | + without_memoizer_hoisted |
| 152 | +); |
| 153 | +criterion_main!(benches); |
0 commit comments