[Python-checkins] commit of r41698 - sandbox/trunk/setuptools/pkg_resources.py

phillip.eby python-checkins at python.org
Thu Dec 15 19:10:11 CET 2005


Author: phillip.eby
Date: Thu Dec 15 19:10:10 2005
New Revision: 41698

Modified:
   sandbox/trunk/setuptools/pkg_resources.py
Log:
Improve startup performance when sys.path contains a lot of eggs, by
caching normalized versions of path entries.  It appears that 
normalizing paths using os.path.realpath is extremely expensive on
at least Windows.  Caching cuts the overhead by around 30X.


Modified: sandbox/trunk/setuptools/pkg_resources.py
==============================================================================
--- sandbox/trunk/setuptools/pkg_resources.py	(original)
+++ sandbox/trunk/setuptools/pkg_resources.py	Thu Dec 15 19:10:10 2005
@@ -1357,7 +1357,7 @@
 
 def find_on_path(importer, path_item, only=False):
     """Yield distributions accessible on a sys.path directory"""
-    path_item = normalize_path(path_item)
+    path_item = _normalize_cached(path_item)
 
     if os.path.isdir(path_item):
         if path_item.lower().endswith('.egg'):
@@ -1478,9 +1478,9 @@
     """Compute an ns-package subpath for a filesystem or zipfile importer"""
 
     subpath = os.path.join(path_item, packageName.split('.')[-1])
-    normalized = normalize_path(subpath)
+    normalized = _normalize_cached(subpath)
     for item in module.__path__:
-        if normalize_path(item)==normalized:
+        if _normalize_cached(item)==normalized:
             break
     else:
         # Only return the path if it's not already there
@@ -1500,6 +1500,12 @@
     """Normalize a file/dir name for comparison purposes"""
     return os.path.normcase(os.path.realpath(filename))
 
+def _normalize_cached(filename,_cache={}):
+    try:
+        return _cache[filename]
+    except KeyError:
+        _cache[filename] = result = normalize_path(filename)
+        return result
 
 def _set_parent_ns(packageName):
     parts = packageName.split('.')
@@ -1509,12 +1515,6 @@
         setattr(sys.modules[parent], name, sys.modules[packageName])
 
 
-
-
-
-
-
-
 def yield_lines(strs):
     """Yield non-empty/non-comment lines of a ``basestring`` or sequence"""
     if isinstance(strs,basestring):
@@ -1876,7 +1876,7 @@
     #@classmethod
     def from_filename(cls,filename,metadata=None):
         return cls.from_location(
-            normalize_path(filename), os.path.basename(filename), metadata
+            _normalize_cached(filename), os.path.basename(filename), metadata
         )
     from_filename = classmethod(from_filename)
 
@@ -1915,7 +1915,7 @@
             self.check_version_conflict()
         best, pos = 0, -1
         for p,item in enumerate(path):
-            item = normalize_path(item)
+            item = _normalize_cached(item)
             if loc.startswith(item) and len(item)>best and loc<>item:
                 best, pos = len(item), p
         if pos==-1:


More information about the Python-checkins mailing list