[Python-Dev] Re: opcode performance measurements

Jeremy Hylton jeremy@alum.mit.edu
Thu, 31 Jan 2002 06:02:17 -0500


>>>>> "JE" == Jeff Epler <jepler@unpythonic.dhs.org> writes:

  JE> On Thu, Jan 31, 2002 at 05:14:28AM -0500, Jeremy Hylton wrote:
  >> PS Skip-- Sorry the PEP isn't clear, but the only dictionary
  >> lookups that need to occur are at function creation time.
  >> MAKE_FUNCTION would need to lookup the offsets of the globals
  >> used by the functions, so that a LOAD_FAST_GLOBAL opcode would
  >> take an int argument.

  JE> So how does this work for mutually-recursive functions?
  JE>     def f(x):
  JE> 	if x==1: return 1 return g(x)

  JE>     def g(x): return x * f(x-1)

  JE> can f not optimize the load of the global g into a
  JE> LOAD_FAST_GLOBAL?

  JE> PS Which PEP?  I only see 266

PEP 267.  (They gesture at each other.)

So you've got a module with two globals f() and g().  They're stored
in slots 0 and 1 of the module globals array.  When f() and g() are
compiled, the symbol table for the module can note the location of f()
and g() and that f() and g() contain references to globals.  Instead
of emitting LOAD_GLOBAL "f" in g(), you can emit LOAD_GLOBAL 0 ("f").

The complication here is that a code object isn't tied to a single
module.  It would be possible to to exec f.func_code in some other
environment where "g" was not stored in the module global array.  The
dictionary lookups may occur in MAKE_FUNCTION in order to verify that
the code object and the module object agree on the layout of the
globals array.

Jeremy