Replaced the loop-based year/month/day extraction in update_from_seconds with Ben Joffe's "Very Fast 64-bit" date algorithm using multiply-shift division (4 multiplications, 0 hardware divisions). Also replaced the mktime inverse with Ben Joffe's inverse date algorithm. Updated is_leap_year to use the Drepper-Neri-Schneider algorithm (% 25 instead of % 100). Replaced the O(n) yday month-length loop with a constant-time cumulative-days table lookup. Uses UInt128 for portable 128-bit support across 64-bit (native) and 32-bit (software fallback) targets. Raman's benchmarks on x86-64 show a ~13% wall-time improvement: Before: real 2.215s, user 2.214s After: real 1.919s, user 1.913s Algorithm references: https://www.benjoffe.com/fast-date-64 https://www.benjoffe.com/fast-date#inverse https://www.benjoffe.com/fast-leap-year#drepper-neri-schneider --------- Co-authored-by: Raman Tenneti <rtenneti@google.com>
2.3 KiB
(date_and_time)=
Date and Time
LLVM-libc implements the C and POSIX date and time functions (gmtime,
mktime, etc.) using high-performance algorithms and a 64-bit time_t.
This page documents the design decisions and limitations of the implementation.
Calendar Model
LLVM-libc uses the proleptic Gregorian calendar: the modern Gregorian leap-year rules (divisible by 4, except centuries, except quad-centuries) are extended to all dates, including those before the calendar's adoption on October 15, 1582.
This is the model required by the C and POSIX standards. It means that dates
before 1582 do not correspond to historical Julian calendar dates. For
example, gmtime will report February 29 for the year 400 CE, even though
that date was reckoned differently under the Julian calendar in use at the
time.
Leap Seconds
POSIX §4.16 defines each day as exactly 86 400 seconds. LLVM-libc follows
this convention: leap seconds are not represented and time_t values map
to UTC times that ignore leap-second insertions.
64-bit time_t
LLVM-libc requires a 64-bit time_t. A 32-bit time_t is not
supported. This avoids the Year 2038 problem and provides a valid
range of approximately ±2 billion years from the Unix epoch (January 1, 1970).
Algorithms
The date conversion functions use Ben Joffe's "Very Fast 64-bit" date
algorithm, which replaces the traditional loop-based year/month/day extraction
with multiply-shift division (four multiplications, zero hardware divisions).
The inverse (mktime) path uses the companion inverse algorithm from the
same article series. Leap-year testing uses the Drepper–Neri–Schneider
algorithm (modulo 25 instead of modulo 100).
These algorithms are described in:
128-bit intermediate arithmetic is used for the multiply-shift steps. On
64-bit targets this maps to the native __uint128_t; on 32-bit targets
LLVM-libc's software UInt<128> implementation is used, preserving
correctness at a modest performance cost.