diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py
index 562c0bd3edacd8328659e29017f452835b53bde5..5b80e93d6b89e994c385b8e20bd34255dd069122 100644
--- a/lib/spack/spack/directory_layout.py
+++ b/lib/spack/spack/directory_layout.py
@@ -31,6 +31,7 @@
 from contextlib import closing
 
 import llnl.util.tty as tty
+from llnl.util.lang import memoized
 from llnl.util.filesystem import join_path, mkdirp
 
 import spack
@@ -223,6 +224,9 @@ def read_spec(self, path):
 
         if all(spack.db.exists(s.name) for s in spec.traverse()):
             copy = spec.copy()
+
+            # TODO: It takes a lot of time to normalize every spec on read.
+            # TODO: Storing graph info with spec files would fix this.
             copy.normalize()
             if copy.concrete:
                 return copy   # These are specs spack still understands.
@@ -276,17 +280,20 @@ def make_path_for_spec(self, spec):
         self.write_spec(spec, spec_file_path)
 
 
+    @memoized
     def all_specs(self):
         if not os.path.isdir(self.root):
-            return
+            return []
 
+        specs = []
         for path in traverse_dirs_at_depth(self.root, 3):
             arch, compiler, last_dir = path
             spec_file_path = join_path(
                 self.root, arch, compiler, last_dir, self.spec_file_name)
             if os.path.exists(spec_file_path):
                 spec = self.read_spec(spec_file_path)
-                yield spec
+                specs.append(spec)
+        return specs
 
 
     def extension_file_path(self, spec):
diff --git a/lib/spack/spack/packages.py b/lib/spack/spack/packages.py
index 3c81863c113fd96c7996a7b2a76c3dce85ff0cc9..43c4c191c1f50257b7b91a4fbc4c474d69c284ac 100644
--- a/lib/spack/spack/packages.py
+++ b/lib/spack/spack/packages.py
@@ -192,6 +192,7 @@ def all_packages(self):
             yield self.get(name)
 
 
+    @memoized
     def exists(self, pkg_name):
         """Whether a package with the supplied name exists ."""
         return os.path.exists(self.filename_for_package_name(pkg_name))