-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reducing memory footprint by reusing Intl.DateTimeFormat instances #7
Comments
I was wrong about what was making non-ISO calendars so slow. I thought the problem was `formatToParts()`, but it turns out that the `DateTimeFormat` constructor is really slow and also allocates ridiculous amounts of RAM. See more details here: https://bugs.chromium.org/p/v8/issues/detail?id=6528 @littledan in https://bugs.chromium.org/p/v8/issues/detail?id=6528#c4 recommended to cache DateTimeFormat instances, so that's what this commit does. The result is a 6x speedup in non-ISO calendar tests. Before: 6398.83ms After: 1062.26ms A similar speedup is likely for `ES.GetCanonicalTimeZoneIdentifier`. Caching time zone canonicalization (in a separate PR) should have a big positive impact on ZonedDateTIme and TimeZone perf. Many thanks to @fer22f for uncovering this optimization in js-temporal/temporal-polyfill#7.
@fer22f - Really good detective work to isolate this problem to @fer22f - The workaround that @littledan proposed is exactly what you're suggesting doing above: cache instances of The same optimization also has a huge positive impact on non-ISO calendar performance: those tests run about 10x faster. See #8. intl.mjs also uses DateTimeFormat, but making that more efficient probably requires a different approach. See #9. @fer22f - Would you be interested in making a PR to optimize |
Sure, I have some code ready. Mostly https://github.com/fer22f/proposal-temporal/commit/5d3b36e6d1d6fb7e7eb0a83d75467dfd2f3beb44 and https://github.com/fer22f/proposal-temporal/commit/64611a1cda8073e251cd686e5876c165466c26c1. I think adding The fact that we can't optimize But I think it's probably okay, and perhaps something that can be documented (?). I just did a search in my codebase for it, and I have 0 calls to |
BTW, I ran some quick tests and it looks like this optimization will at least double the performance of Temporal's test cases, so the improvement in ZonedDateTime and TimeZone perf must be pretty massive given that those are only a small fraction of our tests. Nice!
Yep! Looks OK. Consider refactoring common code into one method. Minor thing: I'd suggest optimizing for the already-cached case: calling
This is correct. |
I was wrong about what was making non-ISO calendars so slow. I thought the problem was `formatToParts()`, but it turns out that the `DateTimeFormat` constructor is really slow and also allocates ridiculous amounts of RAM. See more details here: https://bugs.chromium.org/p/v8/issues/detail?id=6528 @littledan in https://bugs.chromium.org/p/v8/issues/detail?id=6528#c4 recommended to cache DateTimeFormat instances, so that's what this commit does. The result is a 6x speedup in non-ISO calendar tests. Before: 6398.83ms After: 1062.26ms A similar speedup is likely for `ES.GetCanonicalTimeZoneIdentifier`. Caching time zone canonicalization (in a separate PR) should have a big positive impact on ZonedDateTIme and TimeZone perf. Many thanks to @fer22f for uncovering this optimization in js-temporal/temporal-polyfill#7.
I was wrong about what was making non-ISO calendars so slow. I thought the problem was `formatToParts()`, but it turns out that the `DateTimeFormat` constructor is really slow and also allocates ridiculous amounts of RAM. See more details here: https://bugs.chromium.org/p/v8/issues/detail?id=6528 @littledan in https://bugs.chromium.org/p/v8/issues/detail?id=6528#c4 recommended to cache DateTimeFormat instances, so that's what this commit does. The result is a 6x speedup in non-ISO calendar tests. Before: 6398.83ms After: 1062.26ms A similar speedup is likely for `ES.GetCanonicalTimeZoneIdentifier`. Caching time zone canonicalization (in a separate PR) should have a big positive impact on ZonedDateTIme and TimeZone perf. Many thanks to @fer22f for uncovering this optimization in js-temporal/temporal-polyfill#7.
|
Hello. I was going to post this on the original proposal-temporal repo, but since the goal there wasn't about making a polyfill for production use, I decided not to. However, since this polyfill has that goal, it seems like a relevant issue.
When using the polyfill, I ran into a deno memory issue (which I reported in denoland/deno#10721). The root problem is that in the polyfill, there are a lot of
new Intl.DateTimeFormat
calls, objects which V8 apparently doesn't clean up as well as it could. After some investigation, I found out node is affected too, albeit some orders of magnitude less.The issue can be demonstrated in Temporal as follows:
Which ranks at ~567M resident memory in node, and ~1033M in (newer) deno.
My solution to this problem originally, was to fork the repo for my personal use and implement a cache for these objects. A
Map
cachesIntlDateTimeFormat
s at every site they are required, as such:Node's memory footprint in that same code above went to ~100K after this change. Deno scored at ~239M (which is about the floor memory usage of deno currently).
This is an issue that V8 could fix, but it can also be done at the library level.
The text was updated successfully, but these errors were encountered: