From eec6745b36a0746b0b0608094f64dde6ac65f0d2 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Tue, 20 Jun 2023 12:16:08 +0200 Subject: [PATCH 1/3] Add parsing benchmark --- Cargo.toml | 5 +++++ benches/parsing.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 benches/parsing.rs diff --git a/Cargo.toml b/Cargo.toml index 5cca12b..676b685 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,3 +40,8 @@ doc-comment = "0.3" rstest = ">= 0.13, <=0.18" rstest_reuse = "0.6" anyhow = "1" +criterion = "0.5" + +[[bench]] +name = "parsing" +harness = false diff --git a/benches/parsing.rs b/benches/parsing.rs new file mode 100644 index 0000000..ac70e88 --- /dev/null +++ b/benches/parsing.rs @@ -0,0 +1,29 @@ +use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; + +pub fn criterion_benchmark(c: &mut Criterion) { + let cases = [ + "+80012340000", + "+61406823897", + "+611900123456", + "+32474091150", + "+34666777888", + "+34612345678", + "+441212345678", + "+13459492311", + "+16137827274", + "+1 520 878 2491", + "+1-520-878-2491", + ]; + + for case in cases { + c.bench_with_input(BenchmarkId::new("parse", case), &case, |b, case| { + b.iter(|| { + let pn = black_box(case); + phonenumber::parse(None, pn) + }) + }); + } +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); From f69abee1481fac0d6d531407bae90020e39c6407 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Tue, 11 Apr 2023 21:23:23 +0200 Subject: [PATCH 2/3] Fit NationalNumber in 64 bits --- src/national_number.rs | 34 +++++++++++++++++++++------------- src/parser/mod.rs | 38 ++++++++++---------------------------- 2 files changed, 31 insertions(+), 41 deletions(-) diff --git a/src/national_number.rs b/src/national_number.rs index 4739094..97e72c3 100644 --- a/src/national_number.rs +++ b/src/national_number.rs @@ -19,7 +19,25 @@ use std::fmt; #[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize, Hash, Debug)] pub struct NationalNumber { pub(crate) value: u64, +} + +impl NationalNumber { + pub fn new(value: u64, zeros: u8) -> Self { + // E.164 specifies a maximum of 15 decimals, which corresponds to slightly over 48.9 bits. + // 56 bits ought to cut it here. + assert!(value < (1 << 56), "number too long"); + Self { + value: ((zeros as u64) << 56) | value, + } + } + /// The number without any leading zeroes. + pub fn value(&self) -> u64 { + self.value & 0x00ffffffffffffff + } + + /// The number of leading zeroes. + /// /// In some countries, the national (significant) number starts with one or /// more "0"s without this being a national prefix or trunk code of some /// kind. For example, the leading zero in the national (significant) number @@ -36,18 +54,8 @@ pub struct NationalNumber { /// /// Clients who use the parsing or conversion functionality of the i18n phone /// number libraries will have these fields set if necessary automatically. - pub(crate) zeros: u8, -} - -impl NationalNumber { - /// The number without any leading zeroes. - pub fn value(&self) -> u64 { - self.value - } - - /// The number of leading zeroes. pub fn zeros(&self) -> u8 { - self.zeros + (self.value >> 56) as u8 } } @@ -59,10 +67,10 @@ impl From for u64 { impl fmt::Display for NationalNumber { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for _ in 0..self.zeros { + for _ in 0..self.zeros() { write!(f, "0")?; } - write!(f, "{}", self.value) + write!(f, "{}", self.value()) } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 658d89d..26a3fc2 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -84,10 +84,10 @@ pub fn parse_with>( source: number.country, }, - national: NationalNumber { - value: number.national.parse()?, - zeros: number.national.chars().take_while(|&c| c == '0').count() as u8, - }, + national: NationalNumber::new( + number.national.parse()?, + number.national.chars().take_while(|&c| c == '0').count() as u8, + ), extension: number.extension.map(|s| Extension(s.into_owned())), carrier: number.carrier.map(|s| Carrier(s.into_owned())), @@ -109,10 +109,7 @@ mod test { source: country::Source::Default, }, - national: NationalNumber { - value: 33316005, - zeros: 0, - }, + national: NationalNumber::new(33316005, 0), extension: None, carrier: None, @@ -200,10 +197,7 @@ mod test { source: country::Source::Number, }, - national: NationalNumber { - value: 64123456, - zeros: 0, - }, + national: NationalNumber::new(64123456, 0), extension: None, carrier: None, @@ -221,10 +215,7 @@ mod test { source: country::Source::Default, }, - national: NationalNumber { - value: 30123456, - zeros: 0, - }, + national: NationalNumber::new(30123456, 0), extension: None, carrier: None, @@ -239,10 +230,7 @@ mod test { source: country::Source::Plus, }, - national: NationalNumber { - value: 2345, - zeros: 0, - }, + national: NationalNumber::new(2345, 0,), extension: None, carrier: None, @@ -257,10 +245,7 @@ mod test { source: country::Source::Default, }, - national: NationalNumber { - value: 12, - zeros: 0, - }, + national: NationalNumber::new(12, 0,), extension: None, carrier: None, @@ -275,10 +260,7 @@ mod test { source: country::Source::Default, }, - national: NationalNumber { - value: 3121286979, - zeros: 0, - }, + national: NationalNumber::new(3121286979, 0), extension: None, carrier: Some("12".into()), From 1f46da55d901d2e1290be64e7c7a0dd19b0c9a11 Mon Sep 17 00:00:00 2001 From: Ruben De Smet Date: Thu, 14 Dec 2023 15:09:24 +0100 Subject: [PATCH 3/3] Allow criterion 0.4 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 676b685..561f9b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ doc-comment = "0.3" rstest = ">= 0.13, <=0.18" rstest_reuse = "0.6" anyhow = "1" -criterion = "0.5" +criterion = ">=0.4, <=0.5" [[bench]] name = "parsing"