From c96e62e33a3908eee0b4183adec0c699ce1356ad Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Wed, 20 Jan 2021 15:18:33 +0100 Subject: [PATCH] startup: save the compiled file-matching regexes, to avoid recompiling This reduces startup time by seven percent (when using the standard set of syntaxes) when opening just one file that doesn't match any syntax, and more than ten percent when opening multiple files. It takes some extra memory, but... not wasting CPU cycles is more important. This addresses https://savannah.gnu.org/bugs/?56433. --- src/color.c | 9 +-------- src/definitions.h | 4 ++-- src/rcfile.c | 8 ++++---- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/color.c b/src/color.c index e0c14a3a..3ad24a45 100644 --- a/src/color.c +++ b/src/color.c @@ -120,17 +120,10 @@ void prepare_palette(void) bool found_in_list(regexlisttype *head, const char *shibboleth) { regexlisttype *item; - regex_t rgx; for (item = head; item != NULL; item = item->next) { - regcomp(&rgx, item->full_regex, NANO_REG_EXTENDED | REG_NOSUB); - - if (regexec(&rgx, shibboleth, 0, NULL, 0) == 0) { - regfree(&rgx); + if (regexec(item->one_rgx, shibboleth, 0, NULL, 0) == 0) return TRUE; - } - - regfree(&rgx); } return FALSE; diff --git a/src/definitions.h b/src/definitions.h index a1dff3ca..d165a698 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -366,8 +366,8 @@ typedef struct colortype { } colortype; typedef struct regexlisttype { - char *full_regex; - /* A regex string to match things that imply a certain syntax. */ + regex_t *one_rgx; + /* A regex to match things that imply a certain syntax. */ struct regexlisttype *next; /* The next regex. */ } regexlisttype; diff --git a/src/rcfile.c b/src/rcfile.c index 474b31d4..3c515717 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -622,9 +622,7 @@ bool compile(const char *expression, int rex_flags, regex_t **packed) regerror(outcome, compiled, message, length); jot_error(N_("Bad regex \"%s\": %s"), expression, message); free(message); - } - if (packed == NULL || outcome != 0) { regfree(compiled); free(compiled); } else @@ -1239,6 +1237,8 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage) /* Now gather any valid regexes and add them to the linked list. */ while (*ptr != '\0') { + regex_t *packed_rgx = NULL; + regexstring = ++ptr; ptr = parse_next_regex(ptr); @@ -1246,12 +1246,12 @@ void grab_and_store(const char *kind, char *ptr, regexlisttype **storage) return; /* If the regex string is malformed, skip it. */ - if (!compile(regexstring, NANO_REG_EXTENDED | REG_NOSUB, NULL)) + if (!compile(regexstring, NANO_REG_EXTENDED | REG_NOSUB, &packed_rgx)) continue; /* Copy the regex into a struct, and hook this in at the end. */ newthing = nmalloc(sizeof(regexlisttype)); - newthing->full_regex = copy_of(regexstring); + newthing->one_rgx = packed_rgx; newthing->next = NULL; if (lastthing == NULL)