diff options
author | Massimiliano Culpo <massimiliano.culpo@gmail.com> | 2023-08-17 14:11:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-17 14:11:49 +0200 |
commit | a022e458668eb400a186dc7b8b0afc26633c6f13 (patch) | |
tree | 2bb2ce9fcb842e7cd139b4a4e99c2ad77c54a6c2 | |
parent | 82685a68d92435dca3b2d6d9dcdc7880f1d7c36a (diff) | |
download | spack-a022e458668eb400a186dc7b8b0afc26633c6f13.tar.gz spack-a022e458668eb400a186dc7b8b0afc26633c6f13.tar.bz2 spack-a022e458668eb400a186dc7b8b0afc26633c6f13.tar.xz spack-a022e458668eb400a186dc7b8b0afc26633c6f13.zip |
ASP-based solver: optimize key to intermediate dicts (#39471)
Computing str(spec) is faster than computing hash(spec), and
since all the abstract specs we deal with come from user configuration
they cannot cover DAG structures that are not captured by str() but
are captured by hash()
-rw-r--r-- | lib/spack/spack/solver/asp.py | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 42f4814006..7710641cb5 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -267,12 +267,14 @@ def _id(thing): @llnl.util.lang.key_ordering class AspFunction(AspObject): + __slots__ = ["name", "args"] + def __init__(self, name, args=None): self.name = name self.args = () if args is None else tuple(args) def _cmp_key(self): - return (self.name, self.args) + return self.name, self.args def __call__(self, *args): """Return a new instance of this function with added arguments. @@ -731,7 +733,9 @@ class PyclingoDriver: """ symbol = head.symbol() if hasattr(head, "symbol") else head - self.out.write("%s.\n" % str(symbol)) + # This is commented out to avoid evaluating str(symbol) when we have no stream + if not isinstance(self.out, llnl.util.lang.Devnull): + self.out.write(f"{str(symbol)}.\n") atom = self.backend.add_atom(symbol) @@ -1363,26 +1367,29 @@ class SpackSolverSetup: self.gen.fact(fn.condition_reason(condition_id, msg)) cache = self._trigger_cache[named_cond.name] - if named_cond not in cache: + + named_cond_key = str(named_cond) + if named_cond_key not in cache: trigger_id = next(self._trigger_id_counter) requirements = self.spec_clauses(named_cond, body=True, required_from=name) - cache[named_cond] = (trigger_id, requirements) - trigger_id, requirements = cache[named_cond] + cache[named_cond_key] = (trigger_id, requirements) + trigger_id, requirements = cache[named_cond_key] self.gen.fact(fn.pkg_fact(named_cond.name, fn.condition_trigger(condition_id, trigger_id))) if not imposed_spec: return condition_id cache = self._effect_cache[named_cond.name] - if imposed_spec not in cache: + imposed_spec_key = str(imposed_spec) + if imposed_spec_key not in cache: effect_id = next(self._effect_id_counter) requirements = self.spec_clauses(imposed_spec, body=False, required_from=name) if not node: requirements = list( filter(lambda x: x.args[0] not in ("node", "virtual_node"), requirements) ) - cache[imposed_spec] = (effect_id, requirements) - effect_id, requirements = cache[imposed_spec] + cache[imposed_spec_key] = (effect_id, requirements) + effect_id, requirements = cache[imposed_spec_key] self.gen.fact(fn.pkg_fact(named_cond.name, fn.condition_effect(condition_id, effect_id))) return condition_id |