From 9c4620242cac23724c849cb40aa93b69bc4eeb5a Mon Sep 17 00:00:00 2001 From: Rose <83477269+AtariDreams@users.noreply.github.com> Date: Mon, 11 Dec 2023 15:51:03 -0500 Subject: [PATCH] Make isleap faster The assembler generated is better if we compare directly instead of doing fancy ring buffer-eque logic. Proof: https://godbolt.org/z/dferPP9h4 --- CoreFoundation/NumberDate.subproj/CFDate.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CoreFoundation/NumberDate.subproj/CFDate.c b/CoreFoundation/NumberDate.subproj/CFDate.c index e6abb43cb22..8052c5d85c2 100644 --- a/CoreFoundation/NumberDate.subproj/CFDate.c +++ b/CoreFoundation/NumberDate.subproj/CFDate.c @@ -249,10 +249,13 @@ static const uint8_t daysInMonth[16] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 3 static const uint16_t daysBeforeMonth[16] = {INVALID_MONTH_RESULT, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, INVALID_MONTH_RESULT, INVALID_MONTH_RESULT}; static const uint16_t daysAfterMonth[16] = {365, 334, 306, 275, 245, 214, 184, 153, 122, 92, 61, 31, 0, 0, 0, 0}; -CF_INLINE bool isleap(int64_t year) { - int64_t y = (year + 1) % 400; /* correct to nearest multiple-of-400 year, then find the remainder */ - if (y < 0) y = -y; - return (0 == (y & 3) && 100 != y && 200 != y && 300 != y); +CF_INLINE bool isleap(int64_t year) +{ + if (year < 0) year = -year; + if (((year & 3) == 0 && (year % 100) != 0) || ((year % 400) == 0)) + return true; + + return false; } /* year arg is absolute year; Gregorian 2001 == year 0; 2001/1/1 = absolute date 0 */