Don’t call spec.format in Database._get_matching_spec_key (#38792)
`"%s" % spec` formats the spec with deps included, which produces sometimes KBs of data and is slow to run in pure Python. It can delay otherwise very short-lived read/write locks on the database. Discovered in #38762 where profile output showed about 2 seconds is spent in `spec.format`, which is significant overhead when using multiprocessing to install from binary cache in parallel (installation often takes <5s for small packages). With this change, `spec.format` no longer shows up in profile output. (This line hasn't changed since Spack v0.9 ;p) * move format() call to custom NoSuchSpecError exception * add a comment saying why, so we can eventually change `Spec.__str__`
This commit is contained in:
parent
3c14569b8e
commit
374fda1063
@ -1216,7 +1216,7 @@ def _get_matching_spec_key(self, spec, **kwargs):
|
||||
match = self.query_one(spec, **kwargs)
|
||||
if match:
|
||||
return match.dag_hash()
|
||||
raise KeyError("No such spec in database! %s" % spec)
|
||||
raise NoSuchSpecError(spec)
|
||||
return key
|
||||
|
||||
@_autospec
|
||||
@ -1672,3 +1672,17 @@ def __init__(self, database, expected, found):
|
||||
@property
|
||||
def database_version_message(self):
|
||||
return f"The expected DB version is '{self.expected}', but '{self.found}' was found."
|
||||
|
||||
|
||||
class NoSuchSpecError(KeyError):
|
||||
"""Raised when a spec is not found in the database."""
|
||||
|
||||
def __init__(self, spec):
|
||||
self.spec = spec
|
||||
super().__init__(spec)
|
||||
|
||||
def __str__(self):
|
||||
# This exception is raised frequently, and almost always
|
||||
# caught, so ensure we don't pay the cost of Spec.__str__
|
||||
# unless the exception is actually printed.
|
||||
return f"No such spec in database: {self.spec}"
|
||||
|
Loading…
Reference in New Issue
Block a user