From d1a423908081aa989dc215e0adb515586707c091 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 30 Jan 2025 23:08:36 -0800 Subject: read-until-match: streamline get_char calls. Similarly to what was done in get_csv, we optimize he use of get_char and unget_char. I see a 7.5% speed improvement in a simple benchmark of the awk macro with the record separator rs set to #/\n/. * regex.c (scan_until_common): Obtain the strm_ops operations of the stream, and pull the low level get_char and unget_char virtual operations from it. Call these directly in the loop. Thereby, we avoid all the type checking overhead in these functions. --- regex.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/regex.c b/regex.c index a5c187ff..ebd7b2f4 100644 --- a/regex.c +++ b/regex.c @@ -3197,6 +3197,10 @@ static val scan_until_common(val self, val regex, val stream_in, val match = nil; val stream = default_arg(stream_in, std_input); val include_match = default_null_arg(include_match_in); + struct strm_ops *ops = coerce(struct strm_ops *, + cobj_ops(self, stream, stream_cls)); + val (*get_char)(val) = ops->get_char; + val (*unget_char)(val, val) = ops->unget_char; regex_machine_init(self, ®m, regex); @@ -3219,13 +3223,13 @@ static val scan_until_common(val self, val regex, val stream_in, switch (regex_machine_feed(®m, c_chr(ch))) { case REGM_FAIL: - unget_char(ch, stream); + unget_char(stream, ch); if (match) goto out_match; while (stack) - unget_char(rcyc_pop(&stack), stream); + unget_char(stream, rcyc_pop(&stack)); ch = get_char(stream); @@ -3259,7 +3263,7 @@ static val scan_until_common(val self, val regex, val stream_in, if (nil) { out_match: while (stack && stack != match) - unget_char(rcyc_pop(&stack), stream); + unget_char(stream, rcyc_pop(&stack)); if (accum && !out) out = null_string; if (include_match) -- cgit v1.2.3