[Python-Dev] 2.3 startup speed?

Jeremy Hylton jeremy@zope.com
11 Jul 2003 13:25:14 -0400


--=-xRJ1W9x+0jsd/L7bf43k
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

On Thu, 2003-07-10 at 16:15, Aahz wrote:
> What's the current status of the startup speed for Python 2.3?  Did
> anyone ever check in fixes for that?

I did some more measurements of what I think are startup time and
teardown time.  I assume people who care about startup time for small
scripts care about teardown time for small scripts, too, since it's time
spent executing code.  (You might consider it time wasted, since the
process is exiting and it's mostly giving memory back to obmalloc <0.5
wink>.)

I measured the time it takes to execute two different scripts:
python -c "pass" and python -c "import os; os._exit(0)".  I believe the
os._exit() script measures just startup time, because the process exits
immediately without running Py_Finalize().  So I'll refer to two times
"total" time and "startup" time for the two scripts.

I took the measurements after the warnings changes I made today.

Times reported here are the minimum of each real, user, and sys time
over 10 runs of the script.  This is on my RH 7.3 desktop.  (Timing
script attached.)

py  kind     real  user   sys  (time in ms)
2.2 total      32    21     2
2.2 startup    29    14     4

2.3 total      53    33     6
2.3 startup    41    21     4

(I took the minimums of the individual component times, so they don't
add up quite right.)

One thing to observe is that the teardown time (the difference between
total and startup) is much larger in 2.3.  It's 3ms in 2.2 and 12ms in
2.3.  We added to extra GC collection phases to 2.3 teardown, so that
isn't too surprising.

One thing I learned is that timings take from a build directory are
quite different from timings taken after an install.  The cost of
loading up distutils is high.

Jeremy


--=-xRJ1W9x+0jsd/L7bf43k
Content-Disposition: attachment; filename=startup.py
Content-Type: text/x-python; name=startup.py; charset=iso-8859-15
Content-Transfer-Encoding: 7bit

#! /usr/bin/env python

"""Simple script to time Python startup time"""

import os

def timeit1(stmt):
    """Return real, user, and sys from single execution."""
    i, o, e = os.popen3('time %s -c "%s"' % (py, stmt))
    buf = e.read()
    i.close()
    o.close()
    e.close()
    return parse_time(buf)

def timeit(stmt, iters=10):
    """Return the lowest real, user, and sys each from iters trials."""
    L = [timeit1(stmt) for i in range(iters)]
    return map(min, zip(*L))

def parse_time(buf):
    real = None
    user = None
    sys = None
    for line in buf.split("\n"):
        if not line:
            continue
        kind, _t = line.split("\t")
        t = int(float(_t[2:-1]) * 1000)
        if kind == "real":
            real = t
        elif kind == "user":
            user = t
        elif kind == "sys":
            sys = t
    return real, user, sys

def main(argv):
    global py
    py = argv[0]

    total = timeit("pass")
    startup = timeit("import os; os._exit(0)")

    print py
    print "kind     real  user   sys  (time in ms)"
    fmt = "%-8s %4s  %4s  %4s"
    print fmt % ("total", total[0], total[1], total[2])
    print fmt % ("startup", startup[0], startup[1], startup[2])

if __name__ == "__main__":
    import sys
    main(sys.argv[1:])

--=-xRJ1W9x+0jsd/L7bf43k--