diff --git a/benches/scripts/intl/collator-compare.js b/benches/scripts/intl/collator-compare.js new file mode 100644 index 00000000000..ffbe97e74e1 --- /dev/null +++ b/benches/scripts/intl/collator-compare.js @@ -0,0 +1,8 @@ +const kIterationCount = 1000; +const collator = new Intl.Collator("en"); + +function main() { + for (let i = 0; i < kIterationCount; i++) { + collator.compare("apple", "banana"); + } +} diff --git a/benches/scripts/intl/collator-construction.js b/benches/scripts/intl/collator-construction.js new file mode 100644 index 00000000000..423eff34343 --- /dev/null +++ b/benches/scripts/intl/collator-construction.js @@ -0,0 +1,10 @@ +const kIterationCount = 100; +const locales = ["en", "de", "ja", "ar", "fr", "es", "zh"]; + +function main() { + for (let i = 0; i < kIterationCount; i++) { + for (const locale of locales) { + new Intl.Collator(locale); + } + } +} diff --git a/benches/scripts/intl/datetimeformat-construction.js b/benches/scripts/intl/datetimeformat-construction.js new file mode 100644 index 00000000000..d1796f0d744 --- /dev/null +++ b/benches/scripts/intl/datetimeformat-construction.js @@ -0,0 +1,10 @@ +const kIterationCount = 100; +const locales = ["en", "de", "ja", "ar", "fr", "es", "zh"]; + +function main() { + for (let i = 0; i < kIterationCount; i++) { + for (const locale of locales) { + new Intl.DateTimeFormat(locale); + } + } +} diff --git a/benches/scripts/intl/datetimeformat-format.js b/benches/scripts/intl/datetimeformat-format.js new file mode 100644 index 00000000000..43252405068 --- /dev/null +++ b/benches/scripts/intl/datetimeformat-format.js @@ -0,0 +1,9 @@ +const kIterationCount = 1000; +const dtf = new Intl.DateTimeFormat("en"); +const date = new Date(2024, 0, 1); + +function main() { + for (let i = 0; i < kIterationCount; i++) { + dtf.format(date); + } +} diff --git a/benches/scripts/intl/datetimeformat-with-options.js b/benches/scripts/intl/datetimeformat-with-options.js new file mode 100644 index 00000000000..f670927bf22 --- /dev/null +++ b/benches/scripts/intl/datetimeformat-with-options.js @@ -0,0 +1,16 @@ +const kIterationCount = 100; + +function main() { + for (let i = 0; i < kIterationCount; i++) { + new Intl.DateTimeFormat("en", { + year: "numeric", + month: "long", + day: "numeric", + }); + new Intl.DateTimeFormat("en", { + hour: "2-digit", + minute: "2-digit", + second: "2-digit", + }); + } +} diff --git a/benches/scripts/intl/listformat-construction.js b/benches/scripts/intl/listformat-construction.js new file mode 100644 index 00000000000..67f779fbbce --- /dev/null +++ b/benches/scripts/intl/listformat-construction.js @@ -0,0 +1,10 @@ +const kIterationCount = 100; +const locales = ["en", "de", "ja", "ar", "fr", "es", "zh"]; + +function main() { + for (let i = 0; i < kIterationCount; i++) { + for (const locale of locales) { + new Intl.ListFormat(locale); + } + } +} diff --git a/benches/scripts/intl/listformat-format.js b/benches/scripts/intl/listformat-format.js new file mode 100644 index 00000000000..6d6d3cae337 --- /dev/null +++ b/benches/scripts/intl/listformat-format.js @@ -0,0 +1,9 @@ +const kIterationCount = 1000; +const lf = new Intl.ListFormat("en"); +const list = ["apple", "banana", "cherry"]; + +function main() { + for (let i = 0; i < kIterationCount; i++) { + lf.format(list); + } +} diff --git a/benches/scripts/intl/numberformat-construction.js b/benches/scripts/intl/numberformat-construction.js new file mode 100644 index 00000000000..6fcdcb56e51 --- /dev/null +++ b/benches/scripts/intl/numberformat-construction.js @@ -0,0 +1,10 @@ +const kIterationCount = 100; +const locales = ["en", "de", "ja", "ar", "fr", "es", "zh"]; + +function main() { + for (let i = 0; i < kIterationCount; i++) { + for (const locale of locales) { + new Intl.NumberFormat(locale); + } + } +} diff --git a/benches/scripts/intl/numberformat-different-options.js b/benches/scripts/intl/numberformat-different-options.js new file mode 100644 index 00000000000..c424782caf7 --- /dev/null +++ b/benches/scripts/intl/numberformat-different-options.js @@ -0,0 +1,9 @@ +const kIterationCount = 100; + +function main() { + for (let i = 0; i < kIterationCount; i++) { + new Intl.NumberFormat("en", { style: "currency", currency: "USD" }); + new Intl.NumberFormat("en", { style: "percent" }); + new Intl.NumberFormat("en", { notation: "scientific" }); + } +} diff --git a/benches/scripts/intl/pluralrules-construction.js b/benches/scripts/intl/pluralrules-construction.js new file mode 100644 index 00000000000..481df5c94cd --- /dev/null +++ b/benches/scripts/intl/pluralrules-construction.js @@ -0,0 +1,10 @@ +const kIterationCount = 100; +const locales = ["en", "de", "ja", "ar", "fr", "es", "zh"]; + +function main() { + for (let i = 0; i < kIterationCount; i++) { + for (const locale of locales) { + new Intl.PluralRules(locale); + } + } +} diff --git a/benches/scripts/intl/pluralrules-select.js b/benches/scripts/intl/pluralrules-select.js new file mode 100644 index 00000000000..5ab62c4dcb6 --- /dev/null +++ b/benches/scripts/intl/pluralrules-select.js @@ -0,0 +1,8 @@ +const kIterationCount = 1000; +const pr = new Intl.PluralRules("en"); + +function main() { + for (let i = 0; i < kIterationCount; i++) { + pr.select(i); + } +} diff --git a/benches/scripts/intl/segmenter-construction.js b/benches/scripts/intl/segmenter-construction.js new file mode 100644 index 00000000000..ba39b2f7403 --- /dev/null +++ b/benches/scripts/intl/segmenter-construction.js @@ -0,0 +1,10 @@ +const kIterationCount = 100; +const locales = ["en", "de", "ja", "ar", "fr", "es", "zh"]; + +function main() { + for (let i = 0; i < kIterationCount; i++) { + for (const locale of locales) { + new Intl.Segmenter(locale); + } + } +} diff --git a/benches/scripts/intl/segmenter-segment.js b/benches/scripts/intl/segmenter-segment.js new file mode 100644 index 00000000000..d48234beec1 --- /dev/null +++ b/benches/scripts/intl/segmenter-segment.js @@ -0,0 +1,9 @@ +const kIterationCount = 100; +const segmenter = new Intl.Segmenter("en"); +const text = "The quick brown fox jumps over the lazy dog."; + +function main() { + for (let i = 0; i < kIterationCount; i++) { + [...segmenter.segment(text)]; + } +} diff --git a/core/engine/src/builtins/intl/date_time_format/mod.rs b/core/engine/src/builtins/intl/date_time_format/mod.rs index a022aff0974..b5a06559b27 100644 --- a/core/engine/src/builtins/intl/date_time_format/mod.rs +++ b/core/engine/src/builtins/intl/date_time_format/mod.rs @@ -79,6 +79,7 @@ impl FormatTimeZone { /// JavaScript `Intl.DateTimeFormat` object. #[derive(Debug, Clone, Trace, Finalize, JsData)] #[boa_gc(unsafe_empty_trace)] // Safety: No traceable types +#[allow(dead_code)] pub(crate) struct DateTimeFormat { locale: Locale, calendar_algorithm: Option, // TODO: Potentially remove ? @@ -88,6 +89,7 @@ pub(crate) struct DateTimeFormat { time_style: Option, time_zone: FormatTimeZone, fieldset: CompositeFieldSet, + formatter: DateTimeFormatter, bound_format: Option, } @@ -268,15 +270,7 @@ impl DateTimeFormat { // information about the specified calendar. let fields = ToLocalTime::from_local_epoch_milliseconds(tz)?; - let formatter = DateTimeFormatter::try_new_with_buffer_provider( - context.intl_provider().erased_provider(), - dtf.borrow().data().locale.clone().into(), - dtf.borrow().data().fieldset, - ) - .map_err(|e| { - JsNativeError::range() - .with_message(format!("failed to load formatter: {e}")) - })?; + let formatter = dtf.borrow().data().formatter.clone(); let dt = fields.to_formattable_datetime(); let tz_info = dtf.borrow().data().time_zone.to_time_zone_info(); @@ -785,6 +779,13 @@ fn create_date_time_format( // 33. If bestFormat has a field [[hour]], then // a. Set dateTimeFormat.[[HourCycle]] to hc. // 34. Return dateTimeFormat. + let formatter = DateTimeFormatter::try_new_with_buffer_provider( + context.intl_provider().erased_provider(), + resolved_locale.clone().into(), + fieldset, + ) + .map_err(|e| JsNativeError::range().with_message(format!("failed to load formatter: {e}")))?; + Ok(JsObject::from_proto_and_data( prototype, DateTimeFormat { @@ -796,6 +797,7 @@ fn create_date_time_format( time_style, time_zone, fieldset, + formatter, bound_format: None, }, ))