From a9652857380afe637e97e694be6a39cb5bd29652 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Tue, 2 Dec 2025 15:14:15 +0000 Subject: [PATCH] perf: Pre-compile regexes in updates/version package Move regex compilation from function bodies to package-level variables to avoid recompilation when parsing version strings. Affected regexes: - semverRe: Matches semantic version format (X.Y.Z-prerelease+build) - rcNumRe: Extracts RC number from prerelease strings These are called multiple times during version comparison and update checks. --- internal/updates/version.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/internal/updates/version.go b/internal/updates/version.go index bb65c0b..2a69362 100644 --- a/internal/updates/version.go +++ b/internal/updates/version.go @@ -12,6 +12,12 @@ import ( "time" ) +// Pre-compiled regexes for performance (avoid recompilation on each call) +var ( + semverRe = regexp.MustCompile(`^(\d+)\.(\d+)\.(\d+)(?:-([^+]+))?(?:\+(.+))?$`) + rcNumRe = regexp.MustCompile(`rc\.?(\d+)`) +) + // Version represents a semantic version type Version struct { Major int @@ -38,9 +44,7 @@ func ParseVersion(versionStr string) (*Version, error) { // Remove 'v' prefix if present versionStr = strings.TrimPrefix(versionStr, "v") - // Regular expression for semantic versioning - re := regexp.MustCompile(`^(\d+)\.(\d+)\.(\d+)(?:-([^+]+))?(?:\+(.+))?$`) - matches := re.FindStringSubmatch(versionStr) + matches := semverRe.FindStringSubmatch(versionStr) if len(matches) == 0 { return nil, fmt.Errorf("invalid version format: %s", versionStr) @@ -405,8 +409,7 @@ func compareInts(a, b int) int { // extractRCNumber extracts the RC number from a prerelease string like "rc.9" or "rc9" func extractRCNumber(prerelease string) int { - re := regexp.MustCompile(`rc\.?(\d+)`) - matches := re.FindStringSubmatch(strings.ToLower(prerelease)) + matches := rcNumRe.FindStringSubmatch(strings.ToLower(prerelease)) if len(matches) > 1 { num, err := strconv.Atoi(matches[1]) if err == nil {