From 94794d061afb007e06cbecad047fca411aa31d7b Mon Sep 17 00:00:00 2001 From: Tom Scogland Date: Tue, 15 Mar 2022 11:53:28 -0700 Subject: [PATCH] optimize instantiation and comparison of versions (#29429) Re-work the checks and comparisons around commit versions, when no commit version is involved the overhead is now in the noise, where one is the overhead is now constant rather than linear. --- lib/spack/spack/version.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/spack/spack/version.py b/lib/spack/spack/version.py index 9108b1feb5e..d3dd01c3a5a 100644 --- a/lib/spack/spack/version.py +++ b/lib/spack/spack/version.py @@ -48,7 +48,7 @@ VALID_VERSION = re.compile(r'^[A-Za-z0-9_.-]+$') # regex for a commit version -COMMIT_VERSION = re.compile(r'^[a-z0-9]{40}$') +COMMIT_VERSION = re.compile(r'^[a-f0-9]{40}$') # regex for version segments SEGMENT_REGEX = re.compile(r'(?:(?P[0-9]+)|(?P[a-zA-Z]+))(?P[_.-]*)') @@ -167,7 +167,14 @@ def __gt__(self, other): class Version(object): """Class to represent versions""" - __slots__ = ['version', 'separators', 'string', 'is_commit', 'commit_lookup'] + __slots__ = [ + "version", + "separators", + "string", + "commit_lookup", + "is_commit", + "commit_version", + ] def __init__(self, string): if not isinstance(string, str): @@ -182,7 +189,7 @@ def __init__(self, string): # An object that can lookup git commits to compare them to versions self.commit_lookup = None - + self.commit_version = None segments = SEGMENT_REGEX.findall(string) self.version = tuple( int(m[0]) if m[0] else VersionStrComponent(m[1]) for m in segments @@ -195,6 +202,8 @@ def _cmp(self, other_lookups=None): commit_lookup = self.commit_lookup or other_lookups if self.is_commit and commit_lookup: + if self.commit_version is not None: + return self.commit_version commit_info = commit_lookup.get(self.string) if commit_info: prev_version, distance = commit_info @@ -203,7 +212,8 @@ def _cmp(self, other_lookups=None): # If commit is exactly a known version, no distance suffix prev_tuple = Version(prev_version).version if prev_version else () dist_suffix = (VersionStrComponent(''), distance) if distance else () - return prev_tuple + dist_suffix + self.commit_version = prev_tuple + dist_suffix + return self.commit_version return self.version