optimize DateTimeOffset.UtcNow by removing redundant verification (#45281)
authorAdam Sitnik <adam.sitnik@gmail.com>
Mon, 30 Nov 2020 17:05:00 +0000 (18:05 +0100)
committerGitHub <noreply@github.com>
Mon, 30 Nov 2020 17:05:00 +0000 (18:05 +0100)
* optimize DateTimeOffset.UtcNow by removing redundant verification, cuts 10% of time on Windows

* Update src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>
src/libraries/System.Private.CoreLib/src/System/DateTimeOffset.cs

index df06b7f..0ba7aaa 100644 (file)
@@ -54,13 +54,15 @@ namespace System
 
         // Constructors
 
+        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)
+        public DateTimeOffset(long ticks, TimeSpan offset) : this(ValidateOffset(offset), ValidateDate(new DateTime(ticks), 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 @@ namespace System
         // 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
+            {
+                DateTime utcNow = DateTime.UtcNow;
+                var result = new DateTimeOffset(0, utcNow);
+
+                Debug.Assert(new DateTimeOffset(utcNow) == result); // ensure lack of verification does not break anything
+
+                return result;
+            }
+        }
 
         public DateTime DateTime => ClockDateTime;