From 5ee92af1d9df281469ef37a40a303969f5d2a4c1 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 3 Sep 2024 10:18:43 -0400 Subject: [PATCH] LibJS+WebContent: Cache the resolved system time zone identifier Even though the underlying time zone is already cached by LibUnicode, JS performs additional expensive lookups with that time zone. There's no need to do those lookups again until the system time zone has changed. --- Tests/LibJS/test-js.cpp | 2 ++ Userland/Libraries/LibJS/Runtime/Date.cpp | 14 +++++++++++++- Userland/Libraries/LibJS/Runtime/Date.h | 1 + .../Services/WebContent/ConnectionFromClient.cpp | 2 ++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Tests/LibJS/test-js.cpp b/Tests/LibJS/test-js.cpp index 74d0cd8db2b..988987dd50c 100644 --- a/Tests/LibJS/test-js.cpp +++ b/Tests/LibJS/test-js.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -109,6 +110,7 @@ TESTJS_GLOBAL_FUNCTION(set_time_zone, setTimeZone) return vm.throw_completion(MUST(String::formatted("Could not set time zone: {}", result.error()))); } + JS::clear_system_time_zone_cache(); Unicode::clear_system_time_zone_cache(); tzset(); diff --git a/Userland/Libraries/LibJS/Runtime/Date.cpp b/Userland/Libraries/LibJS/Runtime/Date.cpp index b36ff27bbcd..e73fa826493 100644 --- a/Userland/Libraries/LibJS/Runtime/Date.cpp +++ b/Userland/Libraries/LibJS/Runtime/Date.cpp @@ -411,9 +411,15 @@ Unicode::TimeZoneOffset get_named_time_zone_offset_nanoseconds(StringView time_z return offset.release_value(); } +static Optional cached_system_time_zone_identifier; + // 21.4.1.24 SystemTimeZoneIdentifier ( ), https://tc39.es/ecma262/#sec-systemtimezoneidentifier String system_time_zone_identifier() { + // OPTIMIZATION: We cache the system time zone to avoid the expensive lookups below. + if (cached_system_time_zone_identifier.has_value()) + return *cached_system_time_zone_identifier; + // 1. If the implementation only supports the UTC time zone, return "UTC". // 2. Let systemTimeZoneString be the String representing the host environment's current time zone, either a primary @@ -429,7 +435,13 @@ String system_time_zone_identifier() } // 3. Return systemTimeZoneString. - return system_time_zone_string; + cached_system_time_zone_identifier = move(system_time_zone_string); + return *cached_system_time_zone_identifier; +} + +void clear_system_time_zone_cache() +{ + cached_system_time_zone_identifier.clear(); } // 21.4.1.25 LocalTime ( t ), https://tc39.es/ecma262/#sec-localtime diff --git a/Userland/Libraries/LibJS/Runtime/Date.h b/Userland/Libraries/LibJS/Runtime/Date.h index 3a2e10e1c6c..aca9a0c3015 100644 --- a/Userland/Libraries/LibJS/Runtime/Date.h +++ b/Userland/Libraries/LibJS/Runtime/Date.h @@ -77,6 +77,7 @@ Crypto::SignedBigInteger get_utc_epoch_nanoseconds(i32 year, u8 month, u8 day, u Vector get_named_time_zone_epoch_nanoseconds(StringView time_zone_identifier, i32 year, u8 month, u8 day, u8 hour, u8 minute, u8 second, u16 millisecond, u16 microsecond, u16 nanosecond); Unicode::TimeZoneOffset get_named_time_zone_offset_nanoseconds(StringView time_zone_identifier, Crypto::SignedBigInteger const& epoch_nanoseconds); String system_time_zone_identifier(); +void clear_system_time_zone_cache(); double local_time(double time); double utc_time(double time); double make_time(double hour, double min, double sec, double ms); diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp index cdba8d60f39..3e8faa38182 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.cpp +++ b/Userland/Services/WebContent/ConnectionFromClient.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -1194,6 +1195,7 @@ void ConnectionFromClient::enable_inspector_prototype(u64) void ConnectionFromClient::system_time_zone_changed() { + JS::clear_system_time_zone_cache(); Unicode::clear_system_time_zone_cache(); }