From 9054f1b0188b94371306ff10ea851e11a0becfcf Mon Sep 17 00:00:00 2001 From: Sacha Verweij Date: Mon, 3 Jan 2022 17:26:08 -0700 Subject: [PATCH] Lift expensive Regex construction from DateFormat method body. Constructing the Regex touched in this commit can represent a significant fraction (e.g. half or better) of the runtime of the DateFormat method touched in this commit. To make this DateFormat method more efficient, let's lift that Regex construction out of that method body. --- stdlib/Dates/src/io.jl | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/stdlib/Dates/src/io.jl b/stdlib/Dates/src/io.jl index 1901661fff0e24..ba0958b57f6133 100644 --- a/stdlib/Dates/src/io.jl +++ b/stdlib/Dates/src/io.jl @@ -332,6 +332,23 @@ const CONVERSION_TRANSLATIONS = IdDict{Type, Any}( Time => (Hour, Minute, Second, Millisecond, Microsecond, Nanosecond, AMPM), ) +# The `DateFormat(format, locale)` method just below consumes the following Regex. +# Constructing this Regex is fairly expensive; doing so in the method itself can +# consume half or better of `DateFormat(format, locale)`'s runtime. So instead we +# construct and cache it outside the method body. Note, however, that when +# `keys(CONVERSION_SPECIFIERS)` changes, the cached Regex must be updated accordingly; +# hence the mutability (Ref-ness) of the cache, the helper method with which to populate +# the cache, the cache of the hash of `keys(CONVERSION_SPECIFIERS)` (to facilitate checking +# for changes), and the lock (to maintain consistency of these objects across threads when +# threads simultaneously modify `CONVERSION_SPECIFIERS` and construct `DateFormat`s). +function compute_dateformat_regex(conversion_specifiers) + letters = String(collect(keys(conversion_specifiers))) + return Regex("(? DateFormat @@ -379,8 +396,20 @@ function DateFormat(f::AbstractString, locale::DateLocale=ENGLISH) prev = () prev_offset = 1 - letters = String(collect(keys(CONVERSION_SPECIFIERS))) - for m in eachmatch(Regex("(? s"\1") if !isempty(prev)