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