From a022e458668eb400a186dc7b8b0afc26633c6f13 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Thu, 17 Aug 2023 14:11:49 +0200 Subject: 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() --- lib/spack/spack/solver/asp.py | 23 +++++++++++++++-------- 1 file 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 -- cgit v1.2.3-70-g09d2