From 1628558e2bb9ddd4deb2c4882401f02dfbf8ce2b Mon Sep 17 00:00:00 2001 From: Frank Winklmeier <frank.winklmeier@cern.ch> Date: Tue, 25 Apr 2023 15:36:12 +0200 Subject: [PATCH 1/2] AthConfigFlags: add cache for hasCategory The lookup of categories can be very slow for jobs with many flags. Add a cache for already found categories. --- .../AthenaConfiguration/python/AthConfigFlags.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Control/AthenaConfiguration/python/AthConfigFlags.py b/Control/AthenaConfiguration/python/AthConfigFlags.py index 9a2a090903df..35e03d5fbc15 100644 --- a/Control/AthenaConfiguration/python/AthConfigFlags.py +++ b/Control/AthenaConfiguration/python/AthConfigFlags.py @@ -144,7 +144,8 @@ class AthConfigFlags(object): self._flagdict=dict() self._locked=False self._dynaflags = dict() - self._loaded = set() # dynamic dlags that were loaded + self._loaded = set() # dynamic dlags that were loaded + self._categoryCache = set() # cache for already found categories self._hash = None self._parser = None self._args = None # user args from parser @@ -251,13 +252,21 @@ class AthConfigFlags(object): self._loadDynaFlags( prefix ) def hasCategory(self, name): - path = name+'.' + # We cache successfully found categories + if name in self._categoryCache: + return True + + # If not found do search through all keys. + # TODO: could be improved by using a trie for _flagdict for f in self._flagdict.keys(): - if f.startswith(path): + if f.startswith(name+'.'): + self._categoryCache.add(name) return True for c in self._dynaflags.keys(): if c.startswith(name): + self._categoryCache.add(name) return True + return False def hasFlag(self, name): -- GitLab From 033329db1459e3713b0131440324af39304849aa Mon Sep 17 00:00:00 2001 From: Frank Winklmeier <frank.winklmeier@cern.ch> Date: Tue, 25 Apr 2023 16:01:44 +0200 Subject: [PATCH 2/2] AthConfigFlags: minor optimization for set and get Avoid duplicate lookups in flags dictionary and streamline error message code. --- .../python/AthConfigFlags.py | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/Control/AthenaConfiguration/python/AthConfigFlags.py b/Control/AthenaConfiguration/python/AthConfigFlags.py index 35e03d5fbc15..21191a6a31db 100644 --- a/Control/AthenaConfiguration/python/AthConfigFlags.py +++ b/Control/AthenaConfiguration/python/AthConfigFlags.py @@ -274,24 +274,20 @@ class AthConfigFlags(object): def _set(self,name,value): self._tryModify() - if name in self._flagdict: + try: self._flagdict[name].set(value) - return - errString="No flag with name \'{}\' found".format( name ) - closestMatch=get_close_matches(name,self._flagdict.keys(),1) - if len(closestMatch)>0: - errString+=". Did you mean \'{}\'?".format( closestMatch[0] ) - raise KeyError(errString) + except KeyError: + closestMatch = get_close_matches(name,self._flagdict.keys(),1) + raise KeyError(f"No flag with name '{name}' found" + + (f". Did you mean '{closestMatch[0]}'?" if closestMatch else "")) def _get(self,name): - if name in self._flagdict: + try: return self._flagdict[name].get(self) - - errString="No flag with name \'{}\' found".format( name ) - closestMatch=get_close_matches(name,self._flagdict.keys(),1) - if len(closestMatch)>0: - errString+=". Did you mean \'{}\'?".format( closestMatch[0] ) - raise KeyError(errString) + except KeyError: + closestMatch = get_close_matches(name,self._flagdict.keys(),1) + raise KeyError(f"No flag with name '{name}' found" + + (f". Did you mean '{closestMatch[0]}'?" if closestMatch else "")) def __call__(self,name): return self._get(name) -- GitLab