From 91ea90c25347a33ab4b7f7d7d390af048b4ab809 Mon Sep 17 00:00:00 2001
From: Todd Gamblin <tgamblin@llnl.gov>
Date: Wed, 18 Dec 2019 14:25:21 -0800
Subject: [PATCH] performance: speed up `spack find` in environments

`Environment.added_specs()` has a loop around calls to
`Package.installed()`, which can result in repeated DB queries.  Optimize
this with a read transaction in `Environment`.
---
 lib/spack/spack/environment.py | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/lib/spack/spack/environment.py b/lib/spack/spack/environment.py
index 2c7a0cf098..4a23c52622 100644
--- a/lib/spack/spack/environment.py
+++ b/lib/spack/spack/environment.py
@@ -25,6 +25,7 @@
 import spack.repo
 import spack.schema.env
 import spack.spec
+import spack.store
 import spack.util.spack_json as sjson
 import spack.util.spack_yaml as syaml
 import spack.config
@@ -1232,13 +1233,16 @@ def added_specs(self):
         Yields the user spec for non-concretized specs, and the concrete
         spec for already concretized but not yet installed specs.
         """
-        concretized = dict(self.concretized_specs())
-        for spec in self.user_specs:
-            concrete = concretized.get(spec)
-            if not concrete:
-                yield spec
-            elif not concrete.package.installed:
-                yield concrete
+        # use a transaction to avoid overhead of repeated calls
+        # to `package.installed`
+        with spack.store.db.read_transaction():
+            concretized = dict(self.concretized_specs())
+            for spec in self.user_specs:
+                concrete = concretized.get(spec)
+                if not concrete:
+                    yield spec
+                elif not concrete.package.installed:
+                    yield concrete
 
     def concretized_specs(self):
         """Tuples of (user spec, concrete spec) for all concrete specs."""
-- 
GitLab