From 2c785a77d2bc73330d85364061c7329e88e98f6b Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Fri, 27 Nov 2020 19:19:49 +0100 Subject: [PATCH 1/3] optimize DateTimeOffset.UtcNow by removing redundant verification, cuts 10% of time on Windows --- .../src/System/DateTimeOffset.cs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs index df06b7f0caf668..11203baef37a2e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs @@ -54,13 +54,15 @@ namespace System // Constructors + private DateTimeOffset(DateTime validDateTime, short validOffsetMinutes) + { + _dateTime = validDateTime; + _offsetMinutes = validOffsetMinutes; + } + // Constructs a DateTimeOffset from a tick count and offset - public DateTimeOffset(long ticks, TimeSpan offset) + public DateTimeOffset(long ticks, TimeSpan offset) : this(ValidateDate(new DateTime(ticks), offset), ValidateOffset(offset)) { - _offsetMinutes = ValidateOffset(offset); - // Let the DateTime constructor do the range checks - DateTime dateTime = new DateTime(ticks); - _dateTime = ValidateDate(dateTime, offset); } // Constructs a DateTimeOffset from a DateTime. For Local and Unspecified kinds, @@ -174,7 +176,18 @@ public DateTimeOffset(int year, int month, int day, int hour, int minute, int se // resolution of the returned value depends on the system timer. public static DateTimeOffset Now => ToLocalTime(DateTime.UtcNow, true); - public static DateTimeOffset UtcNow => new DateTimeOffset(DateTime.UtcNow); + public static DateTimeOffset UtcNow + { + get + { + var utcNow = DateTime.UtcNow; + var result = new DateTimeOffset(validDateTime: utcNow, validOffsetMinutes: 0); + + Debug.Assert(new DateTimeOffset(utcNow) == result); // ensure lack of verification does not break anything + + return result; + } + } public DateTime DateTime => ClockDateTime; From aac24772fb9560fc070fff39d2d7b52fbf9e2c7e Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Fri, 27 Nov 2020 20:22:42 +0100 Subject: [PATCH 2/3] Update src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs Co-authored-by: Stephen Toub --- .../System.Private.CoreLib/src/System/DateTimeOffset.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs index 11203baef37a2e..68aa07c0780cd6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs @@ -180,8 +180,8 @@ public static DateTimeOffset UtcNow { get { - var utcNow = DateTime.UtcNow; - var result = new DateTimeOffset(validDateTime: utcNow, validOffsetMinutes: 0); + DateTime utcNow = DateTime.UtcNow; + var result = new DateTimeOffset(utcNow, validOffsetMinutes: 0); Debug.Assert(new DateTimeOffset(utcNow) == result); // ensure lack of verification does not break anything From c7b3ce23a0c0645bba5ee38db175580b26eee9ab Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Mon, 30 Nov 2020 13:46:01 +0100 Subject: [PATCH 3/3] change the order of arguments to call ValidateOffset before ValidateDate to make sure thrown exceptions do not change --- .../System.Private.CoreLib/src/System/DateTimeOffset.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs index 68aa07c0780cd6..0ba7aaac6a4f10 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs @@ -54,14 +54,14 @@ namespace System // Constructors - private DateTimeOffset(DateTime validDateTime, short validOffsetMinutes) + private DateTimeOffset(short validOffsetMinutes, DateTime validDateTime) { _dateTime = validDateTime; _offsetMinutes = validOffsetMinutes; } // Constructs a DateTimeOffset from a tick count and offset - public DateTimeOffset(long ticks, TimeSpan offset) : this(ValidateDate(new DateTime(ticks), offset), ValidateOffset(offset)) + public DateTimeOffset(long ticks, TimeSpan offset) : this(ValidateOffset(offset), ValidateDate(new DateTime(ticks), offset)) { } @@ -181,7 +181,7 @@ public static DateTimeOffset UtcNow get { DateTime utcNow = DateTime.UtcNow; - var result = new DateTimeOffset(utcNow, validOffsetMinutes: 0); + var result = new DateTimeOffset(0, utcNow); Debug.Assert(new DateTimeOffset(utcNow) == result); // ensure lack of verification does not break anything