Skip to content

Commit 428e676

Browse files
committed
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.
1 parent a3c2798 commit 428e676

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

stdlib/Dates/src/io.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,12 @@ const CONVERSION_TRANSLATIONS = IdDict{Type, Any}(
332332
Time => (Hour, Minute, Second, Millisecond, Microsecond, Nanosecond, AMPM),
333333
)
334334

335+
# The `DateFormat(format, locale)` method just below consumes the following Regex.
336+
# Constructing this Regex is fairly expensive; doing so in the method itself can
337+
# consume half or better of `DateFormat(format, locale)`'s runtime.
338+
const DATEFORMAT_LETTERS = String(collect(keys(CONVERSION_SPECIFIERS)))
339+
const DATEFORMAT_REGEX = Regex("(?<!\\\\)([\\Q$DATEFORMAT_LETTERS\\E])\\1*")
340+
335341
"""
336342
DateFormat(format::AbstractString, locale="english") -> DateFormat
337343
@@ -379,8 +385,7 @@ function DateFormat(f::AbstractString, locale::DateLocale=ENGLISH)
379385
prev = ()
380386
prev_offset = 1
381387

382-
letters = String(collect(keys(CONVERSION_SPECIFIERS)))
383-
for m in eachmatch(Regex("(?<!\\\\)([\\Q$letters\\E])\\1*"), f)
388+
for m in eachmatch(DATEFORMAT_REGEX, f)
384389
tran = replace(f[prev_offset:prevind(f, m.offset)], r"\\(.)" => s"\1")
385390

386391
if !isempty(prev)

0 commit comments

Comments
 (0)