Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Sitnik <adam.sitnik@gmail.com>2019-08-08 18:50:03 +0300
committerMarek Safar <marek.safar@gmail.com>2019-08-08 19:55:19 +0300
commitb15518dd5e487cccf98815d9831d0a4b681269fc (patch)
tree6deff2b66c9370dbfff21f5bb3625acf704ee494 /netcore
parent7c59cd14fe9f888452bfc550b430332e1c883ca1 (diff)
make DateTime.UtcNow 5% faster to minimize the leap second performance impact (#26046)
* make few methods used by DateTime.UtcNow inlinable to minimize the leap second performance regression impact, related to #25728 * apply suggested micro-optimizations Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Diffstat (limited to 'netcore')
-rw-r--r--netcore/System.Private.CoreLib/shared/System/DateTime.cs35
-rw-r--r--netcore/System.Private.CoreLib/shared/System/ThrowHelper.cs31
-rw-r--r--netcore/System.Private.CoreLib/shared/System/TimeSpan.cs4
3 files changed, 55 insertions, 15 deletions
diff --git a/netcore/System.Private.CoreLib/shared/System/DateTime.cs b/netcore/System.Private.CoreLib/shared/System/DateTime.cs
index 2317221b5a7..cc621dae21a 100644
--- a/netcore/System.Private.CoreLib/shared/System/DateTime.cs
+++ b/netcore/System.Private.CoreLib/shared/System/DateTime.cs
@@ -641,32 +641,38 @@ namespace System
// Returns the tick count corresponding to the given year, month, and day.
// Will check the if the parameters are valid.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static long DateToTicks(int year, int month, int day)
{
- if (year >= 1 && year <= 9999 && month >= 1 && month <= 12)
+ if (year < 1 || year > 9999 || month < 1 || month > 12 || day < 1)
{
- int[] days = IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365;
- if (day >= 1 && day <= days[month] - days[month - 1])
- {
- int y = year - 1;
- int n = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
- return n * TicksPerDay;
- }
+ ThrowHelper.ThrowArgumentOutOfRange_BadYearMonthDay();
+ }
+
+ int[] days = IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365;
+ if (day > days[month] - days[month - 1])
+ {
+ ThrowHelper.ThrowArgumentOutOfRange_BadYearMonthDay();
}
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
+
+ int y = year - 1;
+ int n = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
+ return n * TicksPerDay;
}
// Return the tick count corresponding to the given hour, minute, second.
// Will check the if the parameters are valid.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static long TimeToTicks(int hour, int minute, int second)
{
//TimeSpan.TimeToTicks is a family access function which does no error checking, so
//we need to put some error checking out here.
- if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60)
+ if ((uint)hour >= 24 || (uint)minute >= 60 || (uint)second >= 60)
{
- return (TimeSpan.TimeToTicks(hour, minute, second));
+ ThrowHelper.ThrowArgumentOutOfRange_BadHourMinuteSecond();
}
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
+
+ return TimeSpan.TimeToTicks(hour, minute, second);
}
// Returns the number of days in the month given by the year and
@@ -1182,13 +1188,14 @@ namespace System
// Checks whether a given year is a leap year. This method returns true if
// year is a leap year, or false if not.
//
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsLeapYear(int year)
{
if (year < 1 || year > 9999)
{
- throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_Year);
+ ThrowHelper.ThrowArgumentOutOfRange_Year();
}
- return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+ return (year & 3) == 0 && ((year & 15) == 0 || (year % 25) != 0);
}
// Constructs a DateTime from a string. The string must specify a
diff --git a/netcore/System.Private.CoreLib/shared/System/ThrowHelper.cs b/netcore/System.Private.CoreLib/shared/System/ThrowHelper.cs
index e79b785e66e..c8ccd4fb93e 100644
--- a/netcore/System.Private.CoreLib/shared/System/ThrowHelper.cs
+++ b/netcore/System.Private.CoreLib/shared/System/ThrowHelper.cs
@@ -132,6 +132,31 @@ namespace System
}
[DoesNotReturn]
+ internal static void ThrowArgumentOutOfRange_Year()
+ {
+ throw GetArgumentOutOfRangeException(ExceptionArgument.year,
+ ExceptionResource.ArgumentOutOfRange_Year);
+ }
+
+ [DoesNotReturn]
+ internal static void ThrowArgumentOutOfRange_BadYearMonthDay()
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
+ }
+
+ [DoesNotReturn]
+ internal static void ThrowArgumentOutOfRange_BadHourMinuteSecond()
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
+ }
+
+ [DoesNotReturn]
+ internal static void ThrowArgumentOutOfRange_TimeSpanTooLong()
+ {
+ throw new ArgumentOutOfRangeException(null, SR.Overflow_TimeSpanTooLong);
+ }
+
+ [DoesNotReturn]
internal static void ThrowWrongKeyTypeArgumentException<T>(T key, Type targetType)
{
// Generic key to move the boxing to the right hand side of throw
@@ -657,6 +682,8 @@ namespace System
return "elementType";
case ExceptionArgument.arrayIndex:
return "arrayIndex";
+ case ExceptionArgument.year:
+ return "year";
default:
Debug.Fail("The enum value is not defined, please check the ExceptionArgument Enum.");
return "";
@@ -687,6 +714,8 @@ namespace System
return SR.ArgumentOutOfRange_IndexCountBuffer;
case ExceptionResource.ArgumentOutOfRange_Count:
return SR.ArgumentOutOfRange_Count;
+ case ExceptionResource.ArgumentOutOfRange_Year:
+ return SR.ArgumentOutOfRange_Year;
case ExceptionResource.Arg_ArrayPlusOffTooSmall:
return SR.Arg_ArrayPlusOffTooSmall;
case ExceptionResource.NotSupported_ReadOnlyCollection:
@@ -901,6 +930,7 @@ namespace System
endIndex,
elementType,
arrayIndex,
+ year,
}
//
@@ -912,6 +942,7 @@ namespace System
ArgumentOutOfRange_IndexCount,
ArgumentOutOfRange_IndexCountBuffer,
ArgumentOutOfRange_Count,
+ ArgumentOutOfRange_Year,
Arg_ArrayPlusOffTooSmall,
NotSupported_ReadOnlyCollection,
Arg_RankMultiDimNotSupported,
diff --git a/netcore/System.Private.CoreLib/shared/System/TimeSpan.cs b/netcore/System.Private.CoreLib/shared/System/TimeSpan.cs
index f08b9048d75..5d5af9a93ba 100644
--- a/netcore/System.Private.CoreLib/shared/System/TimeSpan.cs
+++ b/netcore/System.Private.CoreLib/shared/System/TimeSpan.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Globalization;
+using System.Runtime.CompilerServices;
namespace System
{
@@ -288,13 +289,14 @@ namespace System
return new TimeSpan(value);
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static long TimeToTicks(int hour, int minute, int second)
{
// totalSeconds is bounded by 2^31 * 2^12 + 2^31 * 2^8 + 2^31,
// which is less than 2^44, meaning we won't overflow totalSeconds.
long totalSeconds = (long)hour * 3600 + (long)minute * 60 + (long)second;
if (totalSeconds > MaxSeconds || totalSeconds < MinSeconds)
- throw new ArgumentOutOfRangeException(null, SR.Overflow_TimeSpanTooLong);
+ ThrowHelper.ThrowArgumentOutOfRange_TimeSpanTooLong();
return totalSeconds * TicksPerSecond;
}