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.
This commit is contained in:
rcourtman 2025-12-02 15:14:15 +00:00
parent fd3c57377c
commit a965285738

View file

@ -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 {