ecma402
ecma402 copied to clipboard
Temporal requirement to Intl.DateTimeFormat internal slots
This is try to raise an issue I think we should concern about of the impact from Temporal proposal to ECMA402.
I have started to change the Intl.DateTimeFormat to accept Temporal objects in my prototype now.
After a closer look at the changes in Temporal to ECMA402, in particular the changes to the internal requirement of Intl.DateTimeFormat, as stated in
https://tc39.es/proposal-temporal/#sec-abstract-operations
https://tc39.es/proposal-temporal/#sec-datetimeformat-abstracts
https://tc39.es/proposal-temporal/#sec-properties-of-intl-datetimeformat-prototype-object
https://tc39.es/proposal-temporal/#sec-properties-of-intl-datetimeformat-instances
I am concerned about the memory blow to Intl.DateTimeFormat due to the need to support Temporal. Notice before Temporal, we use construct and hold one icu::SimpleDateFormat to handle the format of date/time
We also reserve space to hold and lazy construct one icu::DateIntervalFormat for formatRange
However, in the Temporal proposal, in order to handle 7 different Temporal object, the AO require us to prepare 14 additional patterns, 7 for format() and 7 for formatRange() as stated in https://tc39.es/proposal-temporal/#table-temporal-patterns and https://tc39.es/proposal-temporal/#sec-properties-of-intl-datetimeformat-instances
This means in v8 implementation, to support such model (different Temporal object formatted by the same Intl.DateTimeFormat need to produce different fields in the string therefore need to different pattern) basically mean we need to reserve additional 7 slots for icu::SimpleDateFormat and additional 7 slots for icu::DateIntervalFormat
I wonder why Temporal group need to design this part this way, instead of making one Intl.DateTimeFormat always produce the same set of fields for different types of Temporal object and just require the user to create different Intl.DateTimeFormat to format each of them?
I file this issue in ECMA402 because this is mainly impacting ECMA402 and I would like to ask people in this community to also take a closer look at that.
@anba @sffc @ryzokuken @gibson042 @zbraniecki @littledan
Glad to have this discussion finally. This is something we decided early on, with the expectation that we may need to revisit given implementer feedback.
Firstly, the spec is a guide, not a rule. The observable behavior should be as stated in the spec, but the implementation could do something quite different. For example, my expectation has been that V8 would leave these fields uninitialized, and initialize them the first time they are needed.
If, for some reason, this is not possible, we could revisit some of the earlier decisions, such as requiring that Intl.DateTimeFormat is constructed with the correct set of fields. However, I'd like to avoid going there unless we really need to.
Here are some possibility for implementation, with the current spec text
- Instead of initialize 1 pattern for format and 1 pattern for range, initialize 8 patterns for format and 8 patterns for range, This will cause huge memory regression and speed regression for Intl.DateTimeFormat object created to format Date
- initialize 1 pattern for format and 1 pattern for range, and lazy initialize the pattern for Temporal and remember it in the object each time the format or format range is called, and free the pattern for Temporal after each format/formatRange call. This mean the implementaiotn will be slow when formatting the Temporal object but will not increase memory usage for those Intl.DateTimeFormat object which a lot of web page now is using to format Date.
- initialize 1 pattern for format and 1 pattern for range, and lazy initialize the pattern for Temporal and remember it in the object each time the format or format range is called, and remember the pattern for Temporal after each format/formatRange and reuse it for the next call. This mean formatting Temporal will not be that slow, but it mean we need to at least add some pointer (> 0) for all the Intl.DateTimeFormat web pages currently use for formating Date. This surely will caused SOME memory regression for those for Date
You may think we can do some cache or lazy initialization. But regardless how we do it, it will cose SOME thing for pre-existing Intl.DateTimeFormate for Date format, while they developer is not even using Temporal. Option #2 will avoid that problem and not cause regression but will make Temporal format slow unnecessarily.
If you can think about a solution which will cost "0 bytes increase" for Intl.DateTimeFormat objects already for all the webpage benchmark then it will be good. Otherwise, I am afraid once we implement it and flip the ship bit, it will cause benchmark regression on memory usage and speed for web page NOT USING TEMPORL YET.
Why we cannot take the Date.toLocaleDateString, toLocaleTimeString toLocaleString approach to address this for Temporal. Another problem with the current 8 patterns design is the resolvedOption() won't truthfuly return the information for Temporal objects because it will only return the resolved value for the pattern for Date, but not for the 7 Temporal data types.
Is there any use case we need to have one Intl.DateTimeFormat to format all different Temporal time "differently"? Why we cannot let Intl.DateTimeFormat to format all Temporal type output the same set of fields? or if using one object for Temporal types is REQUIRED, could we create an Intl.TemporalFormat instead and not touch Intl.DateTimeFormat so the current usage for Date won't got impacted?
I think what is needed is this
- The Temporal.*.toLocaleString, while called without options, of all temporal object will always only output the related fields, this could be done by adding different default values of the option for each Temporal types for toLocaleString, similar to how we handle Date toLocaleString vs toLocaleDateString vs toLocaleTimeString
- If the caller specify an option in the toLocaleString, we should honor it
- The solution should NOT require any Intl.DateTimeFormat to bear any additional cost for Temporal while it is NOT used for formatting Temporal. In other words, there should have no constructor time cost for an Intl.DateTimeFormat object.