[Python-Dev] explanations for more pybench slowdowns

Jeremy Hylton jeremy@digicool.com
Fri, 18 May 2001 18:06:05 -0400 (EDT)


In case anyone else is interested, here are two quick pointers on
running pybench tests under the profiler.

1. To build Python with profiling hooks (Unix only): 
LDFLAGS="-pg" OPT="-pg" configure
make
When you run python it produces a gmon.out file.  To run gprof, pass
it the profile-enable executable and gmon.out.  It's spit out the
results on stdout.

2. Use this handy script (below) to run a single pybench test under
   the profiler and produce the output.

Jeremy

"""Tool to automate profiling of individual pybench benchmarks"""

import os
import re
import tempfile

PYCVS = "/home/jeremy/src/python/dist/src/build-pg/python"
PY152 = "/home/jeremy/src/python/dist/Python-1.5.2/build-pg/python"

rx_grep = re.compile('^([^:]+):(.*)')
rx_decl = re.compile('class (\w+)\(\w+\):')

def find_bench(name):
    p = os.popen("grep %s *.py" % name)
    for line in p.readlines():
        mo = rx_grep.search(line)
        if mo is None:
            continue
        file, text = mo.group(1, 2)
        mo = rx_decl.search(text)
        if mo is None:
            continue
        klass = mo.group(1)
        return file, klass
    return None, None

def write_profile_code(file, klass, path):
    i = file.find(".")
    file = file[:i]
    f = open(path, 'w')
    print >> f, "import %s" % file
    print >> f, "%s.%s().run()" % (file, klass)
    f.close()

def profile(interp, path, result):
    if os.path.exists("gmon.out"):
        os.unlink("gmon.out")
    os.system("PYTHONPATH=. %s %s" % (interp, path))
    if not os.path.exists("gmon.out"):
        raise RuntimeError, "gmon.out not generated by %s" % interp
    os.system("gprof %s gmon.out > %s" % (interp, result))

def main(bench_name):
    file, klass = find_bench(bench_name)
    if file is None:
        raise ValueError, "could not find class %s" % bench_name

    code_path = tempfile.mktemp()
    write_profile_code(file, klass, code_path)

    profile(PYCVS, code_path, "%s.cvs.prof" % bench_name)
    profile(PY152, code_path, "%s.152.prof" % bench_name)

    os.unlink(code_path)

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