[Python-Dev] Fixing #7175: a standard location for Python config files

Andrew Bennetts andrew at bemusement.org
Fri Aug 13 04:00:37 CEST 2010


Antoine Pitrou wrote:
> On Thu, 12 Aug 2010 18:14:44 -0400
> Glyph Lefkowitz <glyph at twistedmatrix.com> wrote:
> > 
> > On Aug 12, 2010, at 6:30 AM, Tim Golden wrote:
> > 
> > > I don't care how many stats we're doing
> > 
> > You might not, but I certainly do.  And I can guarantee you that the
> > authors of command-line tools that have to start up in under ten
> > seconds, for example 'bzr', care too.
> 
> The idea that import time is dominated by stat() calls sounds rather
> undemonstrated (and unlikely) to me.

In the case of bzr startup, the exact breakdown varies depending on a
range of factors like OS and whether the relevant parts of the
filesystem are in the OS cache or not (i.e. is this the first time the
user has run bzr since booting?).

The short answer is that the number of stat calls isn't really the
problem at the moment for bzr, at least not compared to the number of
*directories* Python searches, and the amount of non-trivial work done
at import time by many modules.  But... Your Mileage May Vary.

Here's the longer answer:

I think some stats about this have been posted to this list before, but
some points of interest from the top of my head:

 * the cost of trying and failing to open foomodule.so + foo.so +
   foo.pyc + foo.py in a directory isn't much greater than trying to
   open just one on them.  Once the OS has cached the directory entries
   for that directory subsequent lookups in that directory are fast.
   The experiement is fairly easy:
     - strace -e open,stat64 -o py.strace python -c "something..."
     - by hand, create a .C file that repeats all the stat and open
       in py.strace (it's pretty easy to munge into valid C)
     - and also create one with only the *successful* stat and open
       calls
     - compare them (using /proc/sys/vm/drop_caches or whatever as
       appropriate)
 * each directory probed is a significant cost, especially in the
   "cold boot" case.  So every in sys.path, and every subdirectory of a
   package.
 * that said, Windows seems much slower than Linux on equivalent
   hardware, perhaps attempting to open files is intrinsically more
   expensive there?  Certainly it's not safe to assume conclusions drawn
   on Linux will apply equally well on Windows, or vice versa.
 * modules with many class/function definitions are measurably slower
   than smaller modules.
 * module-level re.compile calls and other non-trivial operations are to
   be avoided, but many modules you depend on will do that.  This
   matters so much that bzr monkey-patches the re module to make
   re.compile lazy.  Try grepping the stdlib to see how many modules do
   re.compile at import time (including as default values of keyword
   args)!
 * it's death by a thousand cuts: each module import probably imports a
   dozen others... by far the simplest way to reduce startup time is to
   just import less modules.  Lazy module imports (bzrlib.lazy_import or
   hg's demandload or whatever) help a lot, and I wish they were a
   builtin feature of Python.
 * I haven't even mentioned NFS or other network filesystems, but you
   can bet they change the picture significantly.

-Andrew.



More information about the Python-Dev mailing list