From addfecb1fa86b204a34ae787827492ff497d654c Mon Sep 17 00:00:00 2001 From: Justin Van Patten Date: Thu, 8 Dec 2016 16:32:56 -0800 Subject: [PATCH] Preallocate the TimeZoneInfo.Utc instance (dotnet/coreclr#8530) There doesn't appear to be a good reason why the TimeZoneInfo.Utc instance needs to be cleared when TimeZoneInfo.ClearCachedData() is called. Instead, we can pre-allocate and reuse a singleton instance, obviating the need for the lazy-initialization/locking mechanics. Commit migrated from https://github.com/dotnet/coreclr/commit/23422d6ca734445094eef27326d86e4845f0b220 --- .../src/mscorlib/src/System/TimeZoneInfo.cs | 50 ++++++---------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/src/coreclr/src/mscorlib/src/System/TimeZoneInfo.cs b/src/coreclr/src/mscorlib/src/System/TimeZoneInfo.cs index 2db8dda..2552d07 100644 --- a/src/coreclr/src/mscorlib/src/System/TimeZoneInfo.cs +++ b/src/coreclr/src/mscorlib/src/System/TimeZoneInfo.cs @@ -115,6 +115,8 @@ namespace System { private const long c_ticksPerDay = c_ticksPerHour * 24; private const long c_ticksPerDayRange = c_ticksPerDay - c_ticksPerMillisecond; + private static readonly TimeZoneInfo s_utcTimeZone = CreateCustomTimeZone(c_utcId, TimeSpan.Zero, c_utcId, c_utcId); + // // All cached data are encapsulated in a helper class to allow consistent view even when the data are refreshed using ClearCachedData() // @@ -125,7 +127,6 @@ namespace System { class CachedData { private volatile TimeZoneInfo m_localTimeZone; - private volatile TimeZoneInfo m_utcTimeZone; private TimeZoneInfo CreateLocal() { @@ -163,31 +164,6 @@ namespace System { } } - private TimeZoneInfo CreateUtc() - { - lock (this) - { - TimeZoneInfo timeZone = m_utcTimeZone; - if (timeZone == null) { - timeZone = CreateCustomTimeZone(c_utcId, TimeSpan.Zero, c_utcId, c_utcId); - m_utcTimeZone = timeZone; - } - return timeZone; - } - } - - public TimeZoneInfo Utc { - get { - Contract.Ensures(Contract.Result() != null); - - TimeZoneInfo timeZone = m_utcTimeZone; - if (timeZone == null) { - timeZone = CreateUtc(); - } - return timeZone; - } - } - // // GetCorrespondingKind- // @@ -215,7 +191,7 @@ namespace System { // in this example. Only when the user passes in TimeZoneInfo.Local or // TimeZoneInfo.Utc to the ConvertTime(...) methods will this check succeed. // - if ((object)timeZone == (object)m_utcTimeZone) { + if ((object)timeZone == (object)s_utcTimeZone) { kind = DateTimeKind.Utc; } else if ((object)timeZone == (object)m_localTimeZone) { @@ -427,7 +403,7 @@ namespace System { } else if (dateTime.Kind == DateTimeKind.Utc) { CachedData cachedData = s_cachedData; - adjustedTime = TimeZoneInfo.ConvertTime(dateTime, cachedData.Utc, this, TimeZoneInfoOptions.None, cachedData); + adjustedTime = TimeZoneInfo.ConvertTime(dateTime, s_utcTimeZone, this, TimeZoneInfoOptions.None, cachedData); } else { adjustedTime = dateTime; @@ -525,7 +501,7 @@ namespace System { // // normal case of converting from Local to Utc and then getting the offset from the UTC DateTime // - DateTime adjustedTime = TimeZoneInfo.ConvertTime(dateTime, cachedData.Local, cachedData.Utc, flags); + DateTime adjustedTime = TimeZoneInfo.ConvertTime(dateTime, cachedData.Local, s_utcTimeZone, flags); return GetUtcOffsetFromUtc(adjustedTime, this); } @@ -592,7 +568,7 @@ namespace System { } else if (dateTime.Kind == DateTimeKind.Utc) { CachedData cachedData = s_cachedData; - adjustedTime = TimeZoneInfo.ConvertTime(dateTime, cachedData.Utc, this, flags, cachedData); + adjustedTime = TimeZoneInfo.ConvertTime(dateTime, s_utcTimeZone, this, flags, cachedData); } else { adjustedTime = dateTime; @@ -759,7 +735,7 @@ namespace System { // be reference equal to the new TimeZoneInfo.Utc // CachedData cachedData = s_cachedData; - return ConvertTime(dateTime, cachedData.Utc, FindSystemTimeZoneById(destinationTimeZoneId), TimeZoneInfoOptions.None, cachedData); + return ConvertTime(dateTime, s_utcTimeZone, FindSystemTimeZoneById(destinationTimeZoneId), TimeZoneInfoOptions.None, cachedData); } else { @@ -809,7 +785,7 @@ namespace System { } CachedData cachedData = s_cachedData; if (dateTime.Kind == DateTimeKind.Utc) { - return ConvertTime(dateTime, cachedData.Utc, destinationTimeZone, TimeZoneInfoOptions.None, cachedData); + return ConvertTime(dateTime, s_utcTimeZone, destinationTimeZone, TimeZoneInfoOptions.None, cachedData); } else { return ConvertTime(dateTime, cachedData.Local, destinationTimeZone, TimeZoneInfoOptions.None, cachedData); @@ -903,7 +879,7 @@ namespace System { // static public DateTime ConvertTimeFromUtc(DateTime dateTime, TimeZoneInfo destinationTimeZone) { CachedData cachedData = s_cachedData; - return ConvertTime(dateTime, cachedData.Utc, destinationTimeZone, TimeZoneInfoOptions.None, cachedData); + return ConvertTime(dateTime, s_utcTimeZone, destinationTimeZone, TimeZoneInfoOptions.None, cachedData); } @@ -917,7 +893,7 @@ namespace System { return dateTime; } CachedData cachedData = s_cachedData; - return ConvertTime(dateTime, cachedData.Local, cachedData.Utc, TimeZoneInfoOptions.None, cachedData); + return ConvertTime(dateTime, cachedData.Local, s_utcTimeZone, TimeZoneInfoOptions.None, cachedData); } @@ -926,12 +902,12 @@ namespace System { return dateTime; } CachedData cachedData = s_cachedData; - return ConvertTime(dateTime, cachedData.Local, cachedData.Utc, flags, cachedData); + return ConvertTime(dateTime, cachedData.Local, s_utcTimeZone, flags, cachedData); } static public DateTime ConvertTimeToUtc(DateTime dateTime, TimeZoneInfo sourceTimeZone) { CachedData cachedData = s_cachedData; - return ConvertTime(dateTime, sourceTimeZone, cachedData.Utc, TimeZoneInfoOptions.None, cachedData); + return ConvertTime(dateTime, sourceTimeZone, s_utcTimeZone, TimeZoneInfoOptions.None, cachedData); } @@ -1156,7 +1132,7 @@ namespace System { static public TimeZoneInfo Utc { get { Contract.Ensures(Contract.Result() != null); - return s_cachedData.Utc; + return s_utcTimeZone; } } -- 2.7.4