repo: avoid unnecessary spec parsing in filename_for_package_name()

`filename_for_package_name()` and `dirname_for_package_name()`
automatically construct a Spec from their arguments, which adds a fair
amount of overhead to importing lots of packages.  Removing this removes
about 11% of the runtime of importing all packages in Spack (9s -> 8s).

- [x] `filename_for_package_name()` and `dirname_for_package_name()` now
  take a string `pkg_name` arguments instead of specs.
This commit is contained in:
Todd Gamblin 2020-01-28 21:36:47 -08:00
parent 85ef1be780
commit a2f8a2321d

View file

@ -932,7 +932,7 @@ def dump_provenance(self, spec, path):
tty.warn("Patch file did not exist: %s" % patch.path) tty.warn("Patch file did not exist: %s" % patch.path)
# Install the package.py file itself. # Install the package.py file itself.
install(self.filename_for_package_name(spec), path) install(self.filename_for_package_name(spec.name), path)
def purge(self): def purge(self):
"""Clear entire package instance cache.""" """Clear entire package instance cache."""
@ -974,20 +974,12 @@ def providers_for(self, vpkg_spec):
def extensions_for(self, extendee_spec): def extensions_for(self, extendee_spec):
return [p for p in self.all_packages() if p.extends(extendee_spec)] return [p for p in self.all_packages() if p.extends(extendee_spec)]
def _check_namespace(self, spec): def dirname_for_package_name(self, pkg_name):
"""Check that the spec's namespace is the same as this repository's."""
if spec.namespace and spec.namespace != self.namespace:
raise UnknownNamespaceError(spec.namespace)
@autospec
def dirname_for_package_name(self, spec):
"""Get the directory name for a particular package. This is the """Get the directory name for a particular package. This is the
directory that contains its package.py file.""" directory that contains its package.py file."""
self._check_namespace(spec) return os.path.join(self.packages_path, pkg_name)
return os.path.join(self.packages_path, spec.name)
@autospec def filename_for_package_name(self, pkg_name):
def filename_for_package_name(self, spec):
"""Get the filename for the module we should load for a particular """Get the filename for the module we should load for a particular
package. Packages for a Repo live in package. Packages for a Repo live in
``$root/<package_name>/package.py`` ``$root/<package_name>/package.py``
@ -996,8 +988,7 @@ def filename_for_package_name(self, spec):
package doesn't exist yet, so callers will need to ensure package doesn't exist yet, so callers will need to ensure
the package exists before importing. the package exists before importing.
""" """
self._check_namespace(spec) pkg_dir = self.dirname_for_package_name(pkg_name)
pkg_dir = self.dirname_for_package_name(spec.name)
return os.path.join(pkg_dir, package_file_name) return os.path.join(pkg_dir, package_file_name)
@property @property