How does Python compare to ?

Paul Jackson pj at sgi.com
Mon Jul 31 18:36:00 EDT 2000


Donn Cave, donn at u.washington.edu wrote:
|> But it has to be partly the interpreter too.

Good grief - does it ever.  On my setup at least,
Python startup is much worse than Perl.

Summary:

    Python does a lot more work loading modules at startup,
    for even the most trivial program, than does Perl.

    1) On SGI Irix 6.5.9m and 180 MHz R5000 MIPS:

	Perl startup: 	 13 msec
	Python startup:	196 msec

    2) On SuSE 6.3 Linux and 400 MHz Pentium II:

	Perl startup:	  9 msec
	Python startup:	 60 msec

    where startup is measured from the time libc loads, until
    the time 'real work' begins (the interpreter reads the
    print command and writes "hi").


Below, I analyze the startup in more detail for the Irix case.
The Linux case is similar, except that proportionately more time
is spent waiting for file system calls, and less cpu-bound in
the application (my Linux box has a faster processor).

All numbers are from "hot" runs -- after first repeating the
same command a few times to get all files accessed into the
buffer cache.  The "cold" buffer times for python also seem
to be much worse than perl, which is not surprising, given
the larger number of files python attempts to access at startup.


Comparing Perl and Python startups on a system:

    SGI Irix 6.5.9m on 128MB 180MHz R5000/SC O2

using versions:

    Perl:   perl5 (5.0 patchlevel 4 subversion 4)
    Python: Python 1.5.2 (#25, Jun 11 1999, 16:45:34)

examining the startup of the two using 'par' to run the following:

    echo 'print "hi"' | perl
    echo 'print "hi"' | python

I see that between the time libc is dynamically loaded (at about
6 msecs after the execve()) until the time that perl/python get
down to business (read the echo'd program and write "hi\n"),
there is a _big_ difference between perl and python.


Perl:

    In this interval, perl does just the following 13 milliseconds
    worth of stuff:

	6mS   sysinfo(_MIPS_SI_PROCESSORS, 0x7fff2d20, 257) = 10
	7mS   open("/usr/lib32/libperl.so.4.4", O_RDONLY, 05) = 4
	7mS   read(4, <...>..., 512) = 512
	7mS   elfmap(4, 0x7fff0f50, 2) = 0x97f0000
	8mS   close(4) OK
	8mS   open("/usr/lib32/libm.so", O_RDONLY, 05) = 4
	8mS   read(4, <...>..., 512) = 512
	8mS   elfmap(4, 0x7fff0f50, 2) = 0x94e0000
	9mS   close(4) OK
       10mS   syssgi(SGI_TOSSTSAVE) OK
       11mS   getpagesize() = 4096
       11mS   brk(0x10015000) OK
       11mS   syssgi(SGI_USE_FP_BCOPY, 0, 0x181, -1, 0x180, 0) = 0
       12mS   brk(0x10025000) OK
       13mS   getuid() = 2324, euid=2324
       13mS   getuid() = 2324, euid=2324
       13mS   getgid() = 20 egid=20
       13mS   getgid() = 20 egid=20
       14mS   time() = 965078506
       14mS   getcontext(0x7fff29d0) = 0
       18mS   getpid() = 1147056, ppid=1142422
       19mS   ioctl(0, __OLD_TCGETA, 0x7fff0170) errno = 89
       19mS   read(0, "print "hi"\n", 4096) = 11

Python:

    In the same interval, python does some 196 milliseconds worth
    of stuff, including 52 open attempts, 34 stat attempts, 67
    sigaction calls, 12 fstat's, 20 close's, 27 brk's, ...

    The opens are mostly to open some 10 modules, where
    each module open requires about 4 attempts, for spam.so,
    spammodule.so, spam.py and spam.pyc.  The modules being
    loaded are:

	exceptions, site, os, posixpath, stat, UserDict, and
	about 4 variants of site-customize (under the main
	python1.5 directory, as well as under plat-irix6, lib-tk
	and lib-dynload).

    The stat's are for each of these potential modules, plus
    looking for the file 'python' in every directory on my
    $PATH, plus 4 stats in the subtree "/usr/lib/locale/C".

    Most of the elapsed time, however, does _not_ seem to be in
    waiting on the system for the above calls (the file calls
    were quick - several per msec - out of cache).  Rather most
    of the time seems to be cpu bound, just after reading in one
    of the modules.  Often, some 10-20 msecs go by, marked only
    by a close() call or two, such as when python is reading a
    couple of nested modules, such as stat and posixpath, and
    closes the child module while still plugging away on the
    parent.

    The stat() search for the python file along $PATH comes
    early (before loading modules) and the sigaction() calls
    come just after loading the exceptions module.

-- 
-- 
I won't rest till it's the best ...	   Software Production Engineer
Paul Jackson (pj at sgi.com; pj at usa.net) 3x1373 http://sam.engr.sgi.com/pj



More information about the Python-list mailing list